/************************************************************************************************
 *   深圳市摩西尔电子有限公司 @版本所有@
 *
 *   此文件为 mc_window 页面函数
 *
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.7.7
 *      内容 : 所有代码
 *************************************************************************************************/
/* exported mc_create_crumbs */
/* exported mc_create_child_crumbs */
/* exported mc_delect_crumb */
/* exported mc_get_sendcard_connect_status */
/* exported mc_get_sendcard_img_rect */
/* exported mc_set_card_img_rect */
/* exported mc_set_box_offset */
/* exported mc_create_cp */
/* exported mc_create_hubcard_window */
/* exported mc_default_card_data */
/* exported mc_sendport_recvcard_img */
/* exported mc_get_port_img_rect */
/* exported mc_select_port */
/* exported mc_sendcard_outport_img_rect */
/* exported mc_get_hubcard_connect */
/* exported mc_set_ary_img_data */
/* exported mc_get_menu */
/* exported mc_close_icon_select */
/* exported mc_delect_card */
/* exported mc_delect_port */
/* exported mc_add_port */
/* exported mc_set_sendcard_img_rect */
/* exported mc_custom_callback */
/* exported obj_lang_map */
/* exported mc_custom_dvi_cfg */
/* exported mc_reset_port */
/* exported mc_reset_all_send */
/* exported mc_send_port_backup */
/* exported mc_hub_card_backup */
/* exported mc_get_sendport_backup_data */
/* exported mc_get_sendcard_backup */
/* exported mc_set_sendcard_backup */
/* exported mc_get_sendport_backup_item */
/* exported mc_update_backup_data */
/* exported mc_update_backup_checkbox_data */
/* exported mc_check_have_hubcard */
/* exported mc_set_backup_msg */
/* exported mc_get_arr_cardname */
/* exported mc_get_backup_name */
/* exported mc_get_request_param */
/* exported mc_update_hub_backup */
/* exported mc_update_page_backup_show */
/* exported mc_get_backup_name_data */
/* exported format_hubport_data */
/* exported mc_get_hubbackup_require_strjson */
/* exported mc_jump_update_hubbackup */
/* exported mc_get_port_radio */
/* exported mc_operate_swiper_slider */
/* exported mc_update_slider_range */

/* global $ */
/* global Swiper */
/* global mc_sdk_param */
/* global g_obj_lang */
/* global mc_ui_lab */
/* global mc_ui_edit */
/* global mc_ui_checkbox */
/* global arr_edit_lang */
/* global mc_edit_valchg */
/* global mc_reset_valchg */
/* global mc_card_input_update */
/* global mc_get_top_data */
/* global mc_set_top_data */
/* global mc_ui_select */
/* global obj_operate_swiper */
/* global mc_filter_tool */
/* global option_init */

// 重置数据{crad_name:{width:"",height:"",left:"",top:""}}
var obj_reset_data = {};
// 端口编辑框控件对象{card_name{width:Objct control, height:Objct control, left:Objct control, top:Objct control}
var obj_edit_control = {};
var ui_port_swiper_idx = 0;

// --------------------------------------------面包屑--------------------------------------------------
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    初始化创建面包屑第一层
 * 参数:
 *    @param { Promise<String> } str_class 添加面包屑元素的class
 *    @param { Promise<String> } str_lang 面包屑项lang_id
 * 返回：
 *    @return { Promise<Boolean> }
 *     true 设置成功
 *     false 参数类型错误
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.7.15
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_crumbs(str_class, str_lang) {
    if ("string" !== typeof str_class || 0 === str_class.length) {
        return false;
    }
    if ("string" !== typeof str_lang || 0 === str_lang.length) {
        return false;
    }
    var str_html = " <div id='mc_crumbs' class='flex_box_horizontal'><div class='crumb_item'><div card_name='S' class='crumb_item_text' onclick='mc_jump_window(this)'><span lang_id='" + str_lang + "'>" + g_obj_lang.get_item_val(str_lang) + "</span><i></i><div></div></div></div></div>";

    // 添加在开头
    $("." + str_class).prepend(str_html);
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建子层面包屑
 * 参数:
 *    @param { Promise<String> } str_lang 本层lang_id
 *    @param { Promise<String> } str_crumb_name 本层窗口name 如S0_P
 * 返回：
 *    @return { Promise<Boolean> }
 *     true 设置成功
 *     false 参数类型错误
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.7.15
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_child_crumbs(str_lang, str_crumb_name) {
    if ("string" !== typeof str_lang || 0 === str_lang.length) {
        return false;
    }
    var arr_idx = str_crumb_name.split("_");
    var obj_last = mc_get_crumb_lang_id();
    var str_html = "<div class='crumb_item'><div card_name='" + str_crumb_name + "' class='crumb_item_text' onclick='mc_jump_window(this)'><span lang_id='" + str_lang + "'>" + g_obj_lang.get_item_val(str_lang) + "</span><i></i><div></div></div></div>";
    var str_port_name = str_crumb_name.substr(0, str_crumb_name.lastIndexOf("_"));

    str_port_name = str_port_name.substr(0, str_port_name.lastIndexOf("_") + 2);
    obj_last.parent().attr("port_name", str_port_name);
    // 设置上一个面包屑信息
    obj_last.children("i").html(Number(arr_idx[arr_idx.length - 3].slice(1)) + 1);
    // port_num当前选中port口索引
    if ("MC_LANG_RECEIVER_CARD" !== str_lang) {
        var str_prev_num = Number(arr_idx[arr_idx.length - 2].slice(1)) + 1;

        obj_last.children("div").html("PORT" + str_prev_num);
    }
    obj_last.parent().append("<div class='icon-arrow-single-right icon_select_box'></div>");
    // 添加当前
    $("#mc_crumbs").append(str_html);
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    删除当前面包屑之后项
 * 参数:
 *    @param { Promise<Object> } obj 当前点击对象
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.7.15
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_delect_crumb(obj) {
    $(obj).parent().nextAll().remove();
    $(obj).next().remove();
    $(obj).children("i").html("").next().html("");
}


//  --------------------------------------------请求----------------------------------------------------
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取发送卡连接状态
 * 参数:
 *    @param { Promise<Function> } fun_callback 回调函数
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.4
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_sendcard_connect_status(fun_callback) {
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_func("HW_SENDCARD_CONNECT");
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        fun_callback(response);
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取发送卡图像配置
 * 参数:
 *    @param { Promise<String> } str_idx 发送卡索引
 *    @param { Promise<Function> } fun_callback 回调函数
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.4
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_sendcard_img_rect(str_idx, fun_callback) {
    if ("function" !== typeof fun_callback) {
        return;
    }
    if ("string" !== typeof str_idx || 0 === str_idx.length) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_func("HW_SENDCARD_IMG_RECT");
    obj_sdk_param.set_param_value(str_idx, "");
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        var str_img_msg = obj_sdk_param.get_param_value(str_idx);

        // 获取发送卡数量，每张发送卡上port数量
        fun_callback(str_img_msg);
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取发送卡输出端口图像区域
 * 参数:
 *    @param { Promise<String> } str_sendcard_idx 发送卡索引
 *    @param { Promise<Function> } fun_callback 回调函数
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.4
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_sendcard_outport_img_rect(str_sendcard_idx, fun_callback) {
    if ("string" !== typeof str_sendcard_idx || 0 === str_sendcard_idx.length) {
        return;
    }
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_func("HW_SENDCARD_OUTPORT_IMG_RECT");

    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_param_value(str_sendcard_idx, "");

    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        var str_param_val = obj_sdk_param.get_param_value(str_sendcard_idx);

        // 获得输出端口图像信息(X:Y:W:H),...
        fun_callback(str_param_val);
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取HUB连接
 * 参数:
 *    @param { Promise<String> } str_idx SEND_IDX:SEND_PORT
 *    @param { Promise<Function> } fun_callback 回调函数 参数 (成功true,HUB数量,HUBPORT数量数组 下标为HUB索引)/(失败false,提示lang_id)
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.4
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_hubcard_connect(str_idx, fun_callback) {
    if ("string" !== typeof str_idx || 0 === str_idx.length) {
        return;
    }
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_func("HW_HUBCARD_CONNECT");
    obj_sdk_param.set_param_value("0", str_idx);
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        var str_port_num = obj_sdk_param.get_attr_val("0", "STATUS");

        if ("" === str_port_num) {
            fun_callback(false);
            return;
        }

        var str_err = obj_sdk_param.get_param_value("ERROR_CODE");

        if (!str_port_num) {
            if ("0x00000000" !== str_err && str_err) {
                fun_callback(false, "MC_LANG_POPOUT_FAILED_GET_HUB_CONNECT_STATUS");
            } else {
                fun_callback(true, 0);
            }
        } else {
            var arr_hub = str_port_num.split(",");
            var arr_hubport_cnt = [];

            for (var idx = 0; idx < arr_hub.length; idx++) {
                var ui_hubport_cnt = Number(arr_hub[idx].split(":")[1]);

                arr_hubport_cnt.push(ui_hubport_cnt);
            }

            fun_callback(true, arr_hub.length, arr_hubport_cnt);
        }

        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取HUB输出端口图像配置
 * 参数:
 *    @param { Promise<String> } str_idx SEND_IDX:SEND_PORT:HUB_IDX
 *    @param { Promise<Function> } fun_callback 回调函数 参数输出端口图像区域(X:Y:W:H),.. HUB卡图像区域根据其输出端口获取
 *    @param { Promise<String> } str_json 请求json字串 可为空
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.4
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_hubcard_outport_img_rect(str_idx, fun_callback, str_json) {
    if ("string" !== typeof str_idx || 0 === str_idx.length) {
        return;
    }
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    if (str_json) {
        obj_sdk_param.set_json(str_json);
    } else {
        obj_sdk_param.set_cmd("GET_PARAM");
        obj_sdk_param.set_func("HW_HUBCARD_OUTPORT_IMG_RECT");
        obj_sdk_param.set_param_value(str_idx, "");
    }

    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        if ("1" === str_idx) {
            fun_callback(response);
        } else {
            obj_sdk_param.set_param_clear();
            obj_sdk_param.set_json(response);
            var str_param_val = obj_sdk_param.get_param_value(str_idx);

            fun_callback(str_param_val);
        }
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取发送卡/HUB输出端口上接收卡数量(连接状态)
 * 参数:
 *    @param { Promise<String> } str_idx SEND_IDX:SEND_PORT:HUB_ID:HUB_PORT 后两项无可忽略
 *    @param { Promise<Function> } fun_callback 回调函数参数为接收卡数量字串如"1"
 *    @param { Promise<String> } str_json 请求json串 可为空
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.4
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_recvcard_connect(str_idx, fun_callback, str_json) {
    if ("string" !== typeof str_idx || 0 === str_idx.length) {
        return;
    }
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();

    if (str_json) {
        obj_sdk_param.set_json(str_json);
    } else {
        obj_sdk_param.set_cmd("GET_PARAM");
        obj_sdk_param.set_func("HW_RECVCARD_CONNECT");
        obj_sdk_param.set_param_value("1", str_idx);
    }

    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback(0);
            return;
        }
        if ("1" === str_idx) {
            fun_callback(response);
        } else {
            obj_sdk_param.set_param_clear();
            obj_sdk_param.set_json(response);
            var str_result = obj_sdk_param.get_attr_val("1", "STATUS");

            if (str_result) {
                fun_callback(str_result);
            } else {
                fun_callback(0);
            }
        }
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取接收卡图像偏移(箱体偏移信息)
 * 参数:
 *    @param { Promise<String> } str_idx (SEND_IDX:SEND_PORT:HUB_ID:HUB_PORT)
 *    @param { Promise<Function> } fun_callback 回调函数参数为图像偏移数据字串(ETH_X,ETH_Y,IMG_X,IMG_Y)
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.5
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_recvcard_offset(str_idx, fun_callback) {
    if ("string" !== typeof str_idx || 0 === str_idx.length) {
        return;
    }
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_func("HW_BOX_OFFSET");
    obj_sdk_param.set_param_value("RECVCARD", str_idx);
    obj_sdk_param.set_attr_val("RECVCARD", "CMD", "");
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        var str_param_val = obj_sdk_param.get_attr_val("RECVCARD", "CMD");

        fun_callback(str_param_val);
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取发送卡输出口备份
 * 参数:
 *    @param { Promise<String> } str_idx 发送卡下标 SEND_IDX
 *    @param { Promise<Number> } ui_port_cnt PORT数量
 *    @param { Promise<Function> } fun_callback
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.05
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_sendcard_backup(str_idx, ui_port_cnt, fun_callback) {
    if ("[object String]" !== Object.prototype.toString.call(str_idx)) {
        return;
    }
    if ("[object Number]" !== Object.prototype.toString.call(ui_port_cnt)) {
        return;
    }
    if ("[object Function]" !== Object.prototype.toString.call(fun_callback)) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_func("HW_SENDCARD_OUTPORT_BACKUP");
    for (var i = 0; i < ui_port_cnt; i++) {
        var str_param = "(" + str_idx + ":" + i + ")";

        obj_sdk_param.set_param_value(str_param, "");
    }

    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        fun_callback(response);
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取/写入 HUB卡备份信息
 * 参数:
 *    @param { Promise<String> } str_json 请求JSON字串
 *    @param { Promise<Function> } fun_callback
 *    @param { Promise<Boolean> } b_white 是否写入 默认读取
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_hubcard_backup(str_json, fun_callback, b_white) {
    if ("[object String]" !== Object.prototype.toString.call(str_json) || 0 === str_json.length) {
        return;
    }
    if ("[object Function]" !== Object.prototype.toString.call(fun_callback)) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_json(str_json);
    if (b_white) {
        obj_sdk_param.set_cmd("SET_PARAM");
    } else {
        obj_sdk_param.set_cmd("GET_PARAM");
    }
    obj_sdk_param.set_func("HW_HUBCARD_BACKUP");
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        fun_callback(response);
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    设置发送卡图像配置
 * 参数:
 *    @param { Promise<Object> } obj_data 卡数据
 *    @param { Promise<Function> } fun_callback 回调函数
 *    @param { Promise<Array> } arr_sendcard_name 允许发送卡name 可为空
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.10.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_set_sendcard_img_rect(obj_data, fun_callback, arr_sendcard_name) {
    if ("function" !== typeof fun_callback) {
        return;
    }
    if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
        return;
    }
    var ary_key = arr_sendcard_name;

    if (!arr_sendcard_name) {
        ary_key = Object.keys(obj_data);
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("SET_PARAM");
    obj_sdk_param.set_func("HW_SENDCARD_IMG_RECT");
    for (var idx = 0; idx < ary_key.length; idx++) {
        var str_key = ary_key[idx];

        // sendcard
        if (-1 === str_key.indexOf("_")) {
            var obj_sendcard = obj_data[str_key];
            var obj_img = obj_sendcard.card_img;

            if (obj_img) {
                obj_sdk_param.set_param_value(String(obj_sendcard.index), "(" + obj_img.left + ":" + obj_img.top + ":" + obj_img.width + ":" + obj_img.height + ")");
            }
        }
    }

    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        fun_callback(obj_sdk_param.get_param_value("ERROR_CODE"));
        return;
    });
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    设置卡类输出端口(sendcaradport/hubcardport)图像配置(写入/固化)
 * 参数:
 *    @param { Promisee<String> } str_fun func name
 *    @param { Promise<String> } str_idx (SEND_IDX:SEND_PORT:HUB_ID:HUB_PORT)
 *    @param { Promisee<String> } str_img 图像信息字串(X:Y:W:H)
 *    @param { Promise<Function> } fun_callback 回调函数参数:请求失败返回当前卡索引及空字符 成功返回当前卡索引及错误码
 *    @param { Promise<Boolean> } b_load 是否固化 可为空
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.5
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_set_card_img_rect(str_fun, str_idx, str_img, fun_callback, b_load) {
    if ("function" !== typeof fun_callback) {
        return;
    }
    if ("string" !== typeof str_fun || 0 === str_fun.length) {
        return;
    }
    if ("string" !== typeof str_idx || 0 === str_idx.length) {
        return;
    }
    if ("string" !== typeof str_img || 0 === str_img.length) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("SET_PARAM");
    obj_sdk_param.set_func(str_fun);
    obj_sdk_param.set_param_value(str_idx, str_img);
    if (b_load) {
        obj_sdk_param.set_attr_val(str_idx, "MEMTYPE", "FLS");
    }
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        fun_callback(obj_sdk_param.get_param_value("ERROR_CODE"));
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    设置接收卡图像偏移(箱体偏移信息)写入/固化
 * 参数:
 *    @param { Promise<String> } str_idx (SEND_IDX:SEND_PORT:HUB_ID:HUB_PORT:RECV_IDX)
 *    @param { Promisee<String> } str_offset_msg (0:0:IMG_X:IMG_Y)偏移信息
 *    @param { Promisee<String> } str_chtrlchip_name 接收卡芯片信息 可为空
 *    @param { Promise<Function> } fun_callback 回调函数参数:错误码
 *    @param { Promise<Boolean> } b_load 是否固化 可为空
 *    @param { Promise<String> } str_workmode 工作模式参数
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.5
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_set_box_offset(str_idx, str_offset_msg, str_chtrlchip_name, fun_callback, b_load, str_workmode) {
    if ("string" !== typeof str_offset_msg || 0 === str_offset_msg.length) {
        return;
    }
    if ("function" !== typeof fun_callback) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("SET_PARAM");
    obj_sdk_param.set_func("HW_BOX_OFFSET");
    obj_sdk_param.set_param_value("RECVCARD", str_idx);
    obj_sdk_param.set_attr_val("RECVCARD", "CMD", str_offset_msg);
    if ("string" === typeof str_chtrlchip_name && "" !== str_chtrlchip_name) {
        obj_sdk_param.set_attr_val("RECVCARD", "CHIPNAME", str_chtrlchip_name);
    }
    if (b_load) {
        obj_sdk_param.set_attr_val("RECVCARD", "MEMTYPE", "FLS");
    } else {
        obj_sdk_param.set_attr_val("RECVCARD", "MEMTYPE", "RAM");
    }
    if (str_workmode) {
        // obj_sdk_param.set_attr_val("RECVCARD","WORKMODE",str_workmode);
    }
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        fun_callback(obj_sdk_param.get_param_value("ERROR_CODE"));
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    设置发送卡输出口备份
 * 参数:
 *    @param { Promise<Object> } obj_data 卡数据
 *    @param { Promise<Function> } fun_callback
 *    @param { Promise<Boolean> } b_load 是否固化
 *    @param { Promise<String> } str_json json数据 可为空
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.05
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_set_sendcard_backup(obj_data, fun_callback, b_load, str_json) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
        return;
    }
    if ("[object Function]" !== Object.prototype.toString.call(fun_callback)) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    if (str_json) {
        obj_sdk_param.set_json(str_json);
    } else {
        var ary_key = Object.keys(obj_data);
        var str_memtype = "RAM";

        if (b_load) {
            str_memtype = "FLASH";
        }
        obj_sdk_param.set_cmd("SET_PARAM");
        obj_sdk_param.set_func("HW_SENDCARD_OUTPORT_BACKUP");
        for (var idx = 0; idx < ary_key.length; idx++) {
            var str_key = ary_key[idx];

            // sendcard
            if (-1 === str_key.indexOf("_")) {
                var obj_sendcard = obj_data[str_key];
                var ui_port_cnt = obj_sendcard.child_num;
                var str_sendcard_idx = obj_sendcard.index;

                for (var index = 0; index < ui_port_cnt; index++) {
                    var obj_port_data = obj_data[str_key + "_P" + index];
                    var str_param_name = "(" + str_sendcard_idx + ":" + index + ")";

                    obj_sdk_param.set_param_value(str_param_name, String(obj_port_data.backup));
                    obj_sdk_param.set_attr_val(str_param_name, "MEMTYPE", str_memtype);
                }
            }
        }
    }

    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        fun_callback(obj_sdk_param.get_param_value("ERROR_CODE"));
        return;
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    设置发送卡输出端口/HUB卡备份
 * 参数:
 *    @param { Promise<Object> } obj_data 卡数据
 *    @param { Promise<Array> } arr_name  [发送卡PORTNAME,,] / [HUBCARDNAME,,,]
 *    @param { Promise<String> } str_fun set_func
 *    @param { Promise<Function> } fun_callback
 *    @param { Promise<b_load> } b_load 是否固化 可为空 true时为固化
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_set_backup_msg(obj_data, arr_name, str_fun, fun_callback, b_load) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_data) || "[object Array]" !== Object.prototype.toString.call(arr_name) || 0 === arr_name.length) {
        return;
    }
    if ("[object String]" !== Object.prototype.toString.call(str_fun) || "[object Function]" !== Object.prototype.toString.call(fun_callback)) {
        return;
    }
    var obj_sdk_param = new mc_sdk_param();
    var str_memtype = "RAM";

    if (b_load) {
        str_memtype = "FLASH";
    }
    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("SET_PARAM");
    obj_sdk_param.set_func(str_fun);
    for (var i = 0; i < arr_name.length; i++) {
        var str_name = arr_name[i];
        var str_param_name = "";

        // 处理备份创建的临时数据
        if ("[object Object]" === Object.prototype.toString.call(str_name) && str_name.backup) {
            str_param_name = mc_get_data_param(str_name.str_hub_name, 0);

            if (0 !== str_param_name.length) {
                str_param_name = "(" + str_param_name[0] + ")";
                obj_sdk_param.set_param_value(str_param_name, str_name.backup);
                obj_sdk_param.set_attr_val(str_param_name, "MEMTYPE", str_memtype);
            }
            continue;
        }

        if (obj_data[str_name] && obj_data[str_name].backup) {
            str_param_name = mc_get_data_param(str_name, 0);

            if (0 !== str_param_name.length) {
                str_param_name = "(" + str_param_name[0] + ")";
                obj_sdk_param.set_param_value(str_param_name, obj_data[str_name].backup);
                obj_sdk_param.set_attr_val(str_param_name, "MEMTYPE", str_memtype);
            }
        }
    }
    $.post("/access_shell", obj_sdk_param.get_json(), function (response, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(response);
        fun_callback(obj_sdk_param.get_param_value("ERROR_CODE"));
        return;
    });
}

//  --------------------------------------------窗口构建----------------------------------------------------
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建CARD
 * 参数:
 *    @param { Promise<Object> } obj_card_data 卡数据对象
 * 返回：
 *    @return { Promise<Boolean> }
 *      false 参数有误
 *      true 创建成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_card(obj_card_data) {
    if ("object" !== typeof obj_card_data) {
        return false;
    }
    // var obj_card = $(".mc_card_box");
    var str_card_name = obj_card_data.name;
    // var str_card_l = "10px";
    // var str_card_t = "10px";
    var str_reset_input_html = mc_create_input_html(["0", "0", "768", "768"], "reset", str_card_name);
    var str_reset_html = "";
    var str_port_box_h = "";

    if (0 !== str_reset_input_html.length) {
        str_reset_html = "<div class='mc_reset_box' reset_card_name='" + str_card_name + "'>" + str_reset_input_html + "<span class='mc_btn icon-reset' onclick='mc_reset_port(this)'></span></div>";
        obj_reset_data[str_card_name] = { left: "0", "top": "0", width: "768", height: "768" };
    }
    var obj_card_input = obj_card_data.card_img;
    var str_card_tip_html = "";
    var str_input_html = "";
    var str_hub_backup_html = "";
    var str_id = new Date().getTime() + (Math.random() * 1000).toFixed(0) + ui_port_swiper_idx++;
    var str_prev_class = "prev" + str_id;
    var str_next_class = "next" + str_id;


    // 读取发送卡大屏配置
    var b_switch = true;

    if (b_switch && -1 === obj_card_data.name.indexOf("H")) {
        mc_io_hw_sendcard_dvi_cfg(0, obj_card_data, function (err, res) {
            if (!err) {
                // console.log("[读取大屏配置回到数据]",res);
                var str_item_html = construct_item_dvi_cfg(res, obj_card_data);
                // var $obj_card = $("#mc_window_box  [card_name='" + obj_card_data.name + "']");
                var $obj_card = $("#certify  [card_name='" + obj_card_data.name + "']");

                if (0 !== $obj_card.length) {
                    var $obj_container = $obj_card.children(".mc_card");
                    var str_html = "<div class='card_dvi_cfg'>" + str_item_html + "</div>";

                    $obj_container.append(str_html);
                    option_init();
                }
            }
        });
    }

    // // 排列位置
    // if (0 < obj_card.length) {
    //     var obj_port = $(".mc_port");
    //     var ui_port_w = obj_port.width();

    //     if (0 <= ui_port_w && 50 >= ui_port_w) {
    //         ui_port_w = 170;
    //     }
    //     str_card_l = (obj_card.width() + ui_port_w) * (obj_card.length % 4) + "px";

    //     if ("0px" === str_card_l) {
    //         str_card_l = "10px";
    //     }

    //     // 控制每行显示4张卡
    //     if (3 < obj_card.length) {
    //         var obj_prev = obj_card.eq(obj_card.length - 4);

    //         str_card_t = obj_prev.height() + obj_prev[0].offsetTop + 20 + "px";
    //     }
    // }

    // 卡输入部分
    if (obj_card_input) {
        var arr_val = [String(obj_card_input.left), String(obj_card_input.top), String(obj_card_input.width), String(obj_card_input.height)];

        // str_port_box_h = "style='height:418px;'";
        str_input_html = mc_create_input_html(arr_val, "input", str_card_name);
        if (0 !== str_input_html.length) {
            str_input_html = "<div class='mc_input'><div class='input_box' card_input='" + str_card_name + "'><div class='port_tip' style='left:auto;right:-72%'>INPUT</div>" + str_input_html + "</div></div>";
        }
    } else {
        var str_backup_lang = "";
        var str_backup_top = "1";

        if ("0" === obj_card_data.backup) {
            str_backup_lang = arr_edit_lang[4];
            str_backup_top = "0";
        } else {
            str_backup_lang = arr_edit_lang[5];
        }
        // HUB备份显示
        str_hub_backup_html = "<div class='card_backup' backup_card_name='" + str_card_name + "' backup=" + str_backup_top + ">" + str_backup_lang + "</div>";
    }
    str_card_tip_html = "<div class='card_tip'><div class='card_name'>" + str_card_name.substr(str_card_name.lastIndexOf("_") + 1, 1) + (Number(obj_card_data.index) + 1) + "</div><div class='card_size'><span class='width'>" + obj_card_data.width + "</span>X<span class='height'>" + obj_card_data.height + "</span></div><div class='card_pot'><span class='left'>" + obj_card_data.left + "</span>,<span class='top'>" + obj_card_data.top + "</span></div>" + str_hub_backup_html + "<span class='mc_btn icon-trash' onclick='mc_delect_card(this)'></span>" + str_reset_html + "</div>";
    var str_mask_html = "<p class='mc_slider_mask'></p>";
    var str_port_swiper = "<div class='mc_port_prev icon-arrow-single-up " + str_prev_class + "'></div><div id='" + str_id + "' class='mc_port_box swiper-container' " + str_port_box_h + "><div class='swiper-wrapper'></div></div><div class='mc_port_next icon-arrow-single-down " + str_next_class + "'></div>";

    // $("#mc_window_box").append("<div class='mc_card_box' style='left:" + str_card_l + ";top:" + str_card_t + "' card_name='" + str_card_name + "'>" + str_input_html + "<div class='mc_card'>" + str_card_tip_html + "</div><div class='mc_port'><div class='mc_port_box' " + str_port_box_h + "></div><span class='mc_btn icon-plus'  onclick='mc_add_port(this)'><span></div></div>");
    obj_operate_swiper.add_slider("<div class='mc_card_box' card_name='" + str_card_name + "'>" + str_input_html + "<div class='mc_card'>" + str_card_tip_html + "</div><div class='mc_port'>" + str_port_swiper + "<span class='mc_btn icon-plus'  onclick='mc_add_port(this)'><span></div>" + str_mask_html + "</div>");
    mc_init_port_swiper("#" + str_id, obj_card_data, str_prev_class, str_next_class);
    return true;
}

// 初始化port swiper
function mc_init_port_swiper(str_id, obj_card_data, str_prev_class, str_next_class) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_card_data)) {
        return false;
    }
    var obj_port_swiper = new Swiper(str_id, {
        direction: "vertical",
        autoHeight: true,
        freeMode: true,
        navigation: {
            prevEl: "." + str_prev_class,
            nextEl: "." + str_next_class
        },
        on: {
            setTranslate: function (swiper) {
                //自定义事件
                if (0 <= swiper) {
                    return false;
                }
                if (obj_port_swiper && obj_port_swiper.str_box_id) {
                    var ui_slider_item_h = this.slides[0].offsetHeight;
                    var ui_max = this.slides.length * ui_slider_item_h - this.el.offsetHeight;

                    // 限制滚动 固定底部
                    if (ui_max < Math.abs(swiper) && obj_port_swiper) {
                        ui_max = 0 - ui_max;
                        $(obj_port_swiper.str_box_id).children(".swiper-wrapper").css({
                            "transform": "translate3d(0px, " + ui_max + "px, 0px)"
                        });
                    }
                }
                return true;
            }
        }
    });
    var obj_prev = document.getElementsByClassName(str_prev_class)[0];
    var obj_next = document.getElementsByClassName(str_next_class)[0];
    var obj_swiper_wrapper = obj_prev.nextSibling.childNodes[0];
    var loop_prve = null;
    var loop_next = null;
    var ui_max = 0;

    // 移入按钮轮播
    obj_prev.onmouseover = function () {
        loop_prve = window.setInterval(function () {
            var ui_len = ++obj_port_swiper.translate;

            ui_len = 0 > ui_len ? ui_len : 0;
            obj_swiper_wrapper.style.transform = "translate3d(0px, " + ui_len + "px, 0px)";
            obj_port_swiper.translate = ui_len;
        }, 0);
    };
    obj_next.onmouseover = function () {
        loop_next = window.setInterval(function () {
            var ui_len = --obj_port_swiper.translate;

            ui_max = ui_max ? ui_max : -(obj_port_swiper.slides.length * obj_port_swiper.slides[0].offsetHeight - obj_port_swiper.el.offsetHeight);
            ui_len = ui_len > ui_max ? ui_len : ui_max;
            obj_swiper_wrapper.style.transform = "translate3d(0px, " + ui_len + "px, 0px)";
            obj_port_swiper.translate = ui_len;
        }, 0);
    };
    obj_prev.onmouseout = function () {
        if (loop_prve) {
            clearInterval(loop_prve);
        }
    };
    obj_next.onmouseout = function () {
        if (loop_next) {
            ui_max = 0;
            clearInterval(loop_next);
        }
    };

    obj_port_swiper.str_box_id = str_id;
    var obj_operate_swiper = new mc_operate_swiper_slider(obj_port_swiper);

    obj_card_data.obj_port_swiper = obj_operate_swiper;
    obj_operate_swiper.set_create_default(false);
    return true;
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建PORT
 * 参数:
 *    @param { Promise<Object> } obj_port_data PORT数据对象
 *    @param { Promise<String> } str_wd_name card name
 * 返回：
 *    @return { Promise<Boolean> }
 *      false 参数有误
 *      true 创建成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_port(obj_port_data, str_wd_name) {
    if ("object" !== typeof obj_port_data) {
        return false;
    }
    if ("string" !== typeof str_wd_name || 0 === str_wd_name.length) {
        return false;
    }
    var b_sendcard_backup = false;
    var str_backup = "1";

    if (-1 === str_wd_name.indexOf("_")) {
        str_backup = String(obj_port_data.backup);
        // 发送卡port口标识
        b_sendcard_backup = true;
    }
    var arr_val = [String(obj_port_data.left), String(obj_port_data.top), String(obj_port_data.width), String(obj_port_data.height)];
    // var obj_card_box = $("div[card_name='" + str_wd_name + "']");
    var str_port_name = obj_port_data.name;
    var str_edit_html = mc_create_input_html(arr_val, false, str_port_name, b_sendcard_backup, String(Number(obj_port_data.index) + 1));
    var str_port_html = "";

    if (0 !== str_edit_html.length) {
        var str_show_num = Number(obj_port_data.child_num);

        // str_port_html = "<div class='edit_box' onclick='mc_select_port(this)' port_name='" + str_port_name + "' child_num='" + str_show_num + "' child_type='" + obj_port_data.child_type + "' idx='" + obj_port_data.index + "'><div class='port_tip'><div>" + str_port_name.substr(str_port_name.lastIndexOf("_") + 1, 1) + (Number(obj_port_data.index) + 1) + "</div><div>" + obj_port_data.child_type + ":" + str_show_num + "</div><span class='mc_btn icon-trash' onclick='mc_delect_port(this)'></span></div>" + str_edit_html + "</div>";
        str_port_html = "<div class='edit_box' onclick='mc_select_port(this)' port_name='" + str_port_name + "' child_num='" + str_show_num + "' child_type='" + obj_port_data.child_type + "' idx='" + obj_port_data.index + "'><div class='port_tip'><div>" + str_port_name.substr(str_port_name.lastIndexOf("_") + 1, 1) + (Number(obj_port_data.index) + 1) + "</div><div>" + obj_port_data.child_type + ":" + str_show_num + "</div></div>" + str_edit_html + "</div>";
    }
    // var obj_port_box = obj_card_box.children(".mc_port");
    // obj_port_box.children(".mc_port_box").append(str_port_html);
    var obj_card_data = parent.G_OBJ_WINDOW_DATA[str_wd_name];

    if (obj_card_data) {
        var obj_swiper = obj_card_data.obj_port_swiper;

        if (obj_swiper) {
            obj_swiper.add_slider(str_port_html);
            obj_swiper.judge_slider_range();
        }
    }

    // 初始化备份checkbox开关
    if (b_sendcard_backup && "0" === str_backup) {
        obj_edit_control[str_port_name].backup.set_dom_val(true);
    }

    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建输入/输出端口html
 * 参数:
 *    @param { Promise<Array> } arr_val 数据数组
 *    @param { Promise<String> } str_create_type 创建类型 input：输入端口 reset：重置口；可为空 默认创建输出端口
 *    @param { Promise<String> } str_card_name card name / port name
 *    @param { Promise<Boolean> } b_backup 是否添加备份输入编辑框 === 发送卡
 *    @param { Promise<String> } str_port 当前PORT下标
 * 备注:
 *    创建卡输入部分 chg发函数为 mc_card_input_update
 *    输出部分 chg函数为 mc_edit_valchg
 *    重置部分 chg函数为 mc_reset_valchg
 * 返回：
 *    @return { Promise<String> }
 *      false 参数有误
 *      html控件字串 如PORT字串
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.10.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_input_html(arr_val, str_create_type, str_card_name, b_backup) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_val)) {
        return false;
    }
    var ary_edit_englang = ["left", "top", "width", "height"];
    var str_edit_html = "";
    var obj_edit = {};

    // ****备份输入框保留
    // if (b_backup) {
    //     // 添加备份输入
    //     ary_edit_englang.push("backup");
    //     arr_val.push(String(str_port));
    // }

    for (var idx_item = 0; idx_item < arr_val.length; idx_item++) {
        var obj_ui_lab = new mc_ui_lab();
        var obj_ui_edit = new mc_ui_edit();
        var str_type = ary_edit_englang[idx_item];

        obj_ui_lab.set_val(arr_edit_lang[idx_item]);
        obj_ui_lab.set_title(arr_edit_lang[idx_item]);
        if ("input" === str_create_type) {
            obj_ui_edit.on_val_chg = mc_card_input_update;
        } else if ("reset" === str_create_type) {
            obj_ui_edit.on_val_chg = mc_reset_valchg;
        } else {
            obj_ui_edit.on_val_chg = mc_edit_valchg;
        }

        obj_ui_edit.set_add_attr([["update", str_type]]);
        obj_ui_edit.set_type("int");
        if ("width" === str_type || "height" === str_type || "backup" === str_type) {
            obj_ui_edit.set_min_val("1");
        }
        obj_ui_edit.set_val(arr_val[idx_item]);
        obj_edit[str_type] = obj_ui_edit;
        str_edit_html += "<div class='edit_item'>" + obj_ui_lab.get_html_txt() + obj_ui_edit.get_html_txt() + "</div>";
    }

    // 临时功能：备份开关
    if (b_backup) {
        var obj_backup_lab = new mc_ui_lab();
        var obj_backup_checkbox = new mc_ui_checkbox();
        var str_backup_lang = arr_edit_lang[6];

        obj_backup_lab.set_val(str_backup_lang);
        obj_backup_lab.set_title(str_backup_lang);
        obj_backup_checkbox.on_val_chg = mc_edit_valchg;
        obj_backup_checkbox.set_add_attr([["update", "backup"]]);
        obj_edit.backup = obj_backup_checkbox;
        str_edit_html += "<div class='edit_item'>" + obj_backup_lab.get_html_txt() + obj_backup_checkbox.get_html_txt() + "</div>";
    }

    // PORT打开窗口 删除按钮
    if ("input" !== str_create_type && "reset" !== str_create_type) {
        str_edit_html += "<div class='edit_item port_btn'><span class='mc_btn icon-box-quick-layout' onclick='mc_open_window(this)'></span><span class='mc_btn icon-trash' onclick='mc_delect_port(this)'></span></div>";
    }

    obj_edit_control[str_card_name] = obj_edit;
    return str_edit_html;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    跳转创建card及port
 * 参数:
 *    @param { Promise<String> } str_name name如S
 *    @param { Promise<Object> } obj_data OBJ_WINDOW_DATA
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_cp(str_name, obj_data) {
    mc_clear_card();
    for (var idx = 0; 20 > idx; idx++) {
        var str_item_name = str_name + idx;
        var obj_val = obj_data[str_item_name];

        if (obj_val) {
            mc_create_card(obj_val);
            if (obj_val.child_num) {
                var ui_child_cnt = Number(obj_val.child_num);

                for (var idx_child = 0; idx_child < Number(ui_child_cnt); idx_child++) {
                    mc_create_port(obj_data[str_item_name + "_P" + idx_child], str_item_name);
                }
                mc_select_first_port();
            }
        } else {
            break;
        }
    }
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    请求 创建HUBCARD及PORT
 * 参数:
 *    @param { Promise<Number> } ui_wd_num hub窗口数量
 *    @param { Promise<String> } str_wd_name 发送卡输出端口name
 *    @param { Promise<String> } str_param 下标索引 SEND_IDX:SEND_PORT
 *    @param { Promise<Object> } obj_data OBJ_WINDOW_DATA
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_hubcard_window(ui_wd_num, str_wd_name, str_param, obj_data) {
    parent.mc_loading_wait();
    mc_clear_card();
    var obj_hub_param = {};
    var index = 0;

    while (index < ui_wd_num) {
        var obj_param = {
            str_hub_name: str_wd_name + "_H" + index,
            str_port_name: str_wd_name
        };

        obj_hub_param[str_param + ":" + index] = obj_param;
        index += 1;
    }
    mc_get_hub_and_hubport_data(obj_hub_param, obj_data, function () {
        parent.mc_loading_wait_remove();
        return;
    }, true);
    return;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    存储HUBPORT数据 创建HUBPORT
 * 参数:
 *    @param { Promise<String> } str_data HUBPORT图像数据字串
 *    @param { Promise<Number> } ui_num 循环次数可为空
 *    @param { Promise<String> } str_name hubcard name
 *    @param { Promise<Object> } obj_data OBJ_WINDOW_DATA
 * 返回：
 *    @return { Promise<Boolean> }
 *      false 参数有误
 *      true 创建成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.5
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_hubport(str_data, ui_num, str_name, obj_data) {
    if ("string" !== typeof str_data || 0 === str_data.length) {
        return false;
    }
    var arr_data = str_data.split(",");
    var obj_param = {};
    var str_item_data = "";
    var str_wd_name = "";

    if (!ui_num) {
        ui_num = 20;
    }

    for (var idx = 0; idx < ui_num; idx++) {
        // (X:Y:W:H)
        str_item_data = arr_data[idx];
        str_wd_name = str_name + "_P" + idx;
        if (!arr_data[idx]) {
            // 参数不够子窗口数量 创建默认
            obj_param = mc_create_window_params(str_wd_name, idx, 0, "CHILD", "MC_LANG_OUTPORT");
        } else {
            obj_param = mc_fm_data_create_param(str_item_data, str_wd_name, idx, 0, "CHILD", "MC_LANG_OUTPORT");
        }
        // 存储HUBPORT数据
        obj_data[str_wd_name] = obj_param;
        // 创建HUBPORT
        mc_create_port(obj_param, str_name);
    }
    mc_select_first_port();
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建 sendcard/hubcard 默认卡
 * 参数:
 *    @param { Promise<String> } str_type 当前卡类型 lang_id
 *    @param { Promise<String> } str_name 当前页面最后一个卡name 可为空
 *    @param { Promisee<Object> } obj_data OBJ_WINDOW_DATA
 * 返回：
 *    @return { Promise<Boolean> }
 *     false 参数有误
 *     true 创建成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_default_card_data(str_type, str_name, obj_data) {
    if ("string" !== typeof str_type || 0 === str_type.length || "object" !== typeof obj_data) {
        return false;
    }
    var ui_idx = 0;
    var str_dname = "";
    var arr_img = [0, 0, 768, 768];

    if (obj_data[str_name]) {
        ui_idx = Number(obj_data[str_name].index);
        str_dname = str_name.slice(0, str_name.length - String(ui_idx).length);
        ui_idx += 1;
    }
    // sendcard
    if ("MC_LANG_BTN_SCREEN_SENDING_CARD" === str_type) {
        var obj_card_input = {
            left: "0",
            top: "0",
            width: "768",
            height: "768"
        };

        if ("" === str_dname) {
            str_dname = "S0";
        } else {
            str_dname += ui_idx;
        }
        obj_data[str_dname] = mc_create_window_params(str_dname, ui_idx, 2, "PORT", str_type, arr_img);
        obj_data[str_dname].card_img = obj_card_input;
        obj_data[str_dname + "_P0"] = mc_create_window_params(str_dname + "_P0", 0, 0, "CHILD", "MC_LANG_OUTPORT", [0, 0, 768, 768]);
        obj_data[str_dname + "_P1"] = mc_create_window_params(str_dname + "_P1", 1, 0, "CHILD", "MC_LANG_OUTPORT", [0, 0, 768, 768]);

        mc_create_card(obj_data[str_dname]);
        mc_create_port(obj_data[str_dname + "_P0"], str_dname);
        mc_create_port(obj_data[str_dname + "_P1"], str_dname);
        mc_select_first_port();
    }
    // hubcard
    if ("MC_LANG_HUB_CARD" === str_type) {
        if ("" === str_dname) {
            // 最后一个导航项
            str_dname = mc_get_crumb_lang_id().attr("card_name");
            str_dname = str_dname.substr(0, str_dname.lastIndexOf("_") + 2);
        }
        mc_create_default_hub();
    }
    return true;

    // hub name->S0_P0_H ui_idx
    function mc_create_default_hub() {
        var str_img = "(0:0:768:768),(0:0:768:768)";
        var str_hub_name = str_dname + ui_idx;
        var str_data = mc_basis_output_get_img(str_img);
        var obj_param = mc_fm_data_create_param(str_data, str_hub_name, ui_idx, 2, "HUBPORT", "MC_LANG_HUB_CARD", obj_data[str_hub_name.substr(0, str_hub_name.lastIndexOf("_"))].backup);
        var obj_port = obj_data[str_dname.substr(0, str_dname.lastIndexOf("_"))];

        // 记录HUB数据
        obj_port.child_type = "HUB";
        obj_data[str_hub_name] = obj_param;
        obj_port.child_num = Number(obj_port.child_num) + 1;
        // 创建HUB
        mc_create_card(obj_param);
        mc_create_hubport(str_img, 2, str_hub_name, obj_data);
        return true;
    }
}


//  --------------------------------------------数据处理----------------------------------------------------
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    初步构造窗口参数对象
 * 参数:
 *    @param { Promise<String> } str_img_data 图像信息字串 可为空 (X:Y:W:H),,
 *    @param { Promisee<Number> } ui_child_num 子窗口数量
 * 返回：
 *    @return { Promise<Boolean> }
 *     false 参数有误
 *     arr_img 窗口参数对象数组
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.5
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_set_ary_img_data(str_img_data, ui_child_num) {
    // || 0 === str_img_data.length
    // 若卡输出端口图像为空 创建默认
    if ("string" !== typeof str_img_data || 0 === ui_child_num) {
        return false;
    }
    if ("number" !== typeof ui_child_num) {
        return false;
    }
    var arr_img = [];

    if (str_img_data && 0 !== str_img_data.length) {
        arr_img = str_img_data.split(",");
        var ui_d_val = ui_child_num - arr_img.length;

        if (0 < ui_d_val) {
            // 需要创建默认
            var ui_index = ui_d_val;

            while (0 < ui_index) {
                arr_img.push("default");
                ui_index--;
            }
        }
    } else {
        // 直接创建默认
        while (0 < ui_child_num) {
            arr_img.push("default");
            ui_child_num--;
        }
    }
    return arr_img;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取发送卡/HUB卡上所有输出端口接收卡数据
 * 参数:
 *    @param { Promise<String> } str_card_name sendcard name
 *    @param { Promise<Object> } obj_data OBJ_WINDOW_DATA
 *    @param { Promise<Function> } fun_callback 回调函数
 * 返回：
 *    @return { Promise<Boolean> }
 *      false 参数有误
 *      true 创建成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_sendport_recvcard_img(str_card_name, obj_data, fun_callback) {
    if ("string" !== typeof str_card_name || 0 === str_card_name.length || "object" !== typeof obj_data || "function" !== typeof fun_callback) {
        return false;
    }
    if (!obj_data[str_card_name]) {
        return false;
    }
    parent.mc_loading_wait();
    var ary_recvcard_name = [];

    get_port_recvcard(0, Number(obj_data[str_card_name].child_num), ary_recvcard_name, obj_data);

    // 递归查找每个输出端口
    function get_port_recvcard(ui_idx, ui_total, arr_recvcard_name, obj_wdata) {
        if (ui_idx < ui_total) {
            var str_port_name = str_card_name + "_P" + ui_idx;
            var obj_port_data = obj_wdata[str_port_name];

            if ("CHILD" === obj_port_data.child_type || 0 === obj_port_data.child_num || "HUB" === obj_port_data.child_type) {
                // 此口下无卡
                get_port_recvcard(++ui_idx, ui_total, arr_recvcard_name, obj_wdata);
                return false;
            }
            if ("RECV" === obj_port_data.child_type && 0 < Number(obj_port_data.child_num)) {
                get_recvcard_img(str_port_name, 0, Number(obj_port_data.child_num), ++ui_idx, ui_total, arr_recvcard_name, obj_wdata);
            } else {
                update_recvcard_name(arr_recvcard_name, obj_wdata);
                parent.mc_loading_wait_remove();
                fun_callback();
            }
        } else {
            // 保存当前发送卡下的所有接收卡name数组 S0.recvcard_name获取
            update_recvcard_name(arr_recvcard_name, obj_wdata);
            parent.mc_loading_wait_remove();
            fun_callback();
        }
        return true;
    }

    // 获取接收卡图像数据
    function get_recvcard_img(str_port_name, ui_idx, ui_total, ui_port_idx, ui_port_total, arr_recvcard_name, obj_wdata) {
        if (ui_idx < ui_total) {
            // 是否有起始name
            var str_origin_name = mc_get_origin_name(str_port_name);
            var arr_param = "";

            if (str_origin_name) {
                // 初始name存在使用其获取请求参数
                arr_param = mc_get_data_param(str_origin_name, 0);
            } else {
                arr_param = mc_get_data_param(str_port_name, 0);
            }
            var str_param = arr_param[0];

            if (2 === arr_param[1]) {
                str_param = str_param + ":0:0:" + ui_idx;
            } else {
                str_param = str_param + ":" + ui_idx;
            }
            // 获取接收卡图像偏移
            mc_get_recvcard_offset("(" + str_param + ")", function (str_recvcard_offset) {
                var obj_param = {};
                var arr_params = [];
                var str_name = str_port_name + "_R" + ui_idx;

                if (str_recvcard_offset && "string" === typeof str_recvcard_offset) {
                    arr_params = mc_fm_img_rece(str_recvcard_offset);
                    // 接收卡默认宽高---------------------------------------
                    arr_params[0] = arr_params[2];
                    arr_params[1] = arr_params[3];
                    arr_params[2] = 168;
                    arr_params[3] = 168;
                    obj_param = mc_create_window_params(str_name, ui_idx, 0, false, "MC_LANG_RECEIVER_CARD", arr_params);
                } else {
                    obj_param = mc_create_window_params(str_name, ui_idx, 0, false, "MC_LANG_RECEIVER_CARD");
                }
                obj_wdata[str_name] = obj_param;
                arr_recvcard_name.push(str_name);
                ui_idx++;
                get_recvcard_img(str_port_name, ui_idx, ui_total, ui_port_idx, ui_port_total, arr_recvcard_name, obj_wdata);
            });
        } else {
            get_port_recvcard(ui_port_idx, ui_port_total, arr_recvcard_name, obj_wdata);
        }
    }

    // 更新当前卡下的接收卡name数组
    function update_recvcard_name(arr_recvcard_name, obj_wdata) {
        if (0 === arr_recvcard_name.length) {
            return;
        }
        var str_recv = "recvcard_name";

        if (obj_wdata[str_card_name][str_recv]) {
            for (var idx = 0; idx < arr_recvcard_name.length; idx++) {
                obj_wdata[str_card_name][str_recv].push(arr_recvcard_name[idx]);
            }
        } else {
            obj_wdata[str_card_name][str_recv] = arr_recvcard_name;
        }
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    构造窗口参数对象
 * 参数:
 *    @param { Promise<String> } str_name 窗口name
 *    @param { Promisee<Number> } idx_cnt 下标索引
 *    @param { Promise<String/Number> } child_num 子窗口数量
 *    @param { Promise<String> } str_type 子窗口类型
 *    @param { Promise<String> } str_lang lang_id
 *    @param { Promise<Array> } arr_img_data 图像数据(为空时则构建默认) [X,Y,W,H]
 *    @param { Promise<String> } str_backup 发送卡输出端口 主/辅标识 0=辅 1=主 可为空
 * 返回：
 *    @return { Promise<Boolean> }
 *     false 参数有误
 *     obj_param 窗口参数对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.5
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_create_window_params(str_name, idx_cnt, child_num, str_type, str_lang, arr_img_data, str_backup) {
    // 测试-------
    if (arr_img_data && "65535" === arr_img_data[0]) {
        arr_img_data = null;
    }
    // -------------
    var ui_x = 0;
    var ui_y = 0;
    var ui_w = 768;
    var ui_h = 768;

    if (arr_img_data && 0 !== arr_img_data.length) {
        ui_x = Number(arr_img_data[0]);
        ui_y = Number(arr_img_data[1]);
        ui_w = Number(arr_img_data[2]);
        ui_h = Number(arr_img_data[3]);

        // 读取宽高为0时 置为1
        if (0 === ui_w) {
            ui_w = 1;
        }
        if (0 === ui_h) {
            ui_h = 1;
        }
    }
    if ("" === child_num) {
        child_num = 0;
    } else {
        child_num = Number(child_num);
    }
    var obj_param = {
        name: str_name,
        width: ui_w,
        height: ui_h,
        left: ui_x,
        top: ui_y,
        index: Number(idx_cnt),
        child_type: str_type,
        child_num: child_num,
        lang_id: str_lang,
        backup: "1"
    };

    if ("0" === str_backup || "1" === str_backup) {
        obj_param.backup = str_backup;
    }

    return obj_param;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    格式化数据获取窗口参数
 * 参数:
 *    @param { Promise<String> } str_data 图像配置参数对象"(X:Y:W:H)"
 *    @param { Promisee<String> } str_name name
 *    @param { Promise<Number> } idx_cnt 下标索引
 *    @param { Promise<String/Number> } child_num 子窗口数量
 *    @param { Promise<String> } str_type 子窗口类型
 *    @param { Promise<String> } str_lang lang_id
 *    @param { Promise<String> } str_backup 发送卡输出口 主/辅标识 可为空
 * 返回：
 *    @return { Promise<Boolean> }
 *     false 参数有误
 *     obj_param 窗口参数对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_fm_data_create_param(str_data, str_name, idx_cnt, child_num, str_type, str_lang, str_backup) {
    if ("string" !== typeof str_data || 0 === str_data.length) {
        return false;
    }
    if ("default" === str_data) {
        // 直接创建默认参数
        var obj_default_param = mc_create_window_params(str_name, idx_cnt, child_num, str_type, str_lang, false, str_backup);

        return obj_default_param;
    }
    if (-1 === str_data.indexOf(":")) {
        return false;
    }
    var arr_params = mc_fm_img_rece(str_data);
    var obj_param = mc_create_window_params(str_name, idx_cnt, child_num, str_type, str_lang, arr_params, str_backup);

    return obj_param;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取HUB卡图像区域(X:Y:W:H) 记录PORT偏移数组
 * 参数:
 *    @param { Promise<String> } str_data 对应输出端口图像偏移字串 (X:Y:W:H),,
 *    @param { Promisee<Array> } arr_port_l left偏移数组 可为空
 *    @param { Promise<Array> } arr_port_t top偏移数组 可为空
 * 返回：
 *    @return { Promise<Boolean> }
 *     false 参数有误
 *     "(X:Y:W:H)" 图像区域
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_basis_output_get_img(str_data, arr_port_l, arr_port_t) {
    if ("string" !== typeof str_data || 0 === str_data.length) {
        return false;
    }
    var arr_data = str_data.split(",");
    var ui_x = Math.pow(2, 32);
    var ui_y = Math.pow(2, 32);
    var ui_max_l = -Math.pow(2, 32);
    var ui_max_t = -Math.pow(2, 32);

    for (var idx = 0; idx < arr_data.length; idx++) {
        var arr_params = mc_fm_img_rece(arr_data[idx]);
        var ui_item_x = Number(arr_params[0]);
        var ui_item_y = Number(arr_params[1]);
        var ui_item_w = ui_item_x + Number(arr_params[2]);
        var ui_item_h = ui_item_y + Number(arr_params[3]);

        if (arr_port_l) {
            arr_port_l.push(ui_item_x);
        }
        if (arr_port_t) {
            arr_port_t.push(ui_item_y);
        }

        if (ui_x > ui_item_x) {
            ui_x = ui_item_x;
        }
        if (ui_y > ui_item_y) {
            ui_y = ui_item_y;
        }
        if (ui_max_l < ui_item_w) {
            ui_max_l = ui_item_w;
        }
        if (ui_max_t < ui_item_h) {
            ui_max_t = ui_item_h;
        }
    }
    var ui_w = ui_max_l - ui_x;
    var ui_h = ui_max_t - ui_y;

    return "(" + ui_x + ":" + ui_y + ":" + ui_w + ":" + ui_h + ")";
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    根据窗口name获取数据参数 如0:0:0
 * 参数:
 *    @param { Promise<String> } str_name 窗口name
 *    @param { Promisee<Number> } ui_idx 舍去后面几位
 *    @param { Promisee<Number> } ui_back 下标回退多少 可为空
 * 返回：
 *    @return { Promise<String> }
 *     "" 参数有误
 *     [请求数据索引，索引个数]
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_data_param(str_name, ui_idx, ui_back) {
    if ("string" !== typeof str_name || 0 === str_name.length || "number" !== typeof ui_idx) {
        return "";
    }
    var arr_req_param = str_name.split("_");
    var str_param = "";
    var ui_param_num = 0;
    var ui_back_cnt = 0;

    if ("number" === typeof ui_back) {
        ui_back_cnt = ui_back;
    }

    for (var idx = 0; idx < arr_req_param.length - ui_idx; idx++) {
        var str_idx = arr_req_param[idx].substr(1);

        if (0 !== str_idx.length) {
            str_param += Number(arr_req_param[idx].substr(1)) - ui_back_cnt + ":";
            ui_param_num++;
        }
    }
    str_param = str_param.substr(0, str_param.length - 1);
    return [str_param, ui_param_num];
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取指定卡所有输出端口数据字串
 * 参数:
 *    @param { Promise<String> } str_card_name card name
 *    @param { Promisee<Object> } obj_data OBJ_WINDOW_DATA
 * 返回：
 *    @return { Promise<String> }
 *     "" 参数有误
 *     (X:Y:W:H),,
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_port_img_rect(str_card_name, obj_data) {
    if ("string" !== typeof str_card_name || 0 === str_card_name.length || "object" !== typeof obj_data) {
        return "";
    }
    var str_img_rect = "";
    var ui_port_cnt = obj_data[str_card_name].child_num;

    for (var idx_port = 0; idx_port < ui_port_cnt; idx_port++) {
        var obj_port_data = obj_data[str_card_name + "_P" + idx_port];
        var str_x = String(obj_port_data.left);
        var str_y = String(obj_port_data.top);
        var str_w = String(obj_port_data.width);
        var str_h = String(obj_port_data.height);

        str_img_rect += "(" + str_x + ":" + str_y + ":" + str_w + ":" + str_h + "),";
    }
    str_img_rect = str_img_rect.slice(0, str_img_rect.length - 1);
    return str_img_rect;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    图像区域字串转为数组 (X:Y:W:H) -> [X,Y,W,H]
 * 参数:
 *    @param { Promise<String> } str_img 图像区域字串
 * 返回：
 *    @return { Promise<Boolean> }
 *     false 参数有误
 *     [X,Y,W,H]
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.17
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_fm_img_rece(str_img) {
    if ("string" !== typeof str_img || 0 === str_img.length) {
        return false;
    }
    // 去除首尾空格及括号
    str_img = str_img.trim().replace(/^(\s|\()+|(\s|\))+$/g, "");
    return str_img.split(":");
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    根据请求数据 获取PORT口接收卡数量及类型对象
 * 参数:
 *    @param { Promise<String> } str_msg T6:多功能卡:FPGA:CNT4-15:未定义 CNT16:前15个总和
 * 返回：
 *    @return { Promise<Object> }
 *      false 参数有误
 *      0:Number 卡类型为未定义卡
 *      obj_recvcard_msg:Object = {
 *          recvcard_num : 此port下接收卡数量Number
 *          recvcard_type : 此port下各接收卡类型(无先后顺序):Array
 *      }
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.21
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_recvcard_msg(str_msg) {
    if ("string" !== typeof str_msg || 0 === str_msg.length) {
        return false;
    }

    // 数据格式有误
    if (-1 === str_msg.indexOf(":")) {
        return 0;
    }
    // 总卡数为0
    var ui_total_cnt = Number(str_msg.slice(str_msg.lastIndexOf(":") + 1));

    if (0 === ui_total_cnt) {
        return 0;
    }

    var arr_type = str_msg.split(":");
    var arr_type_cnt = [];

    for (var idx = 0; 3 > idx; idx++) {
        var ui_cnt = Number(arr_type[idx]);

        // 目前只定义前三种卡类型
        if (0 < ui_cnt) {
            var str_type = "";

            if (0 === idx) {
                str_type = "T6";
            }
            if (1 === idx) {
                str_type = "多功能卡";
            }
            if (2 === idx) {
                str_type = "FPGA";
            }
            if ("" !== str_type) {
                for (var index = 0; index < ui_cnt; index++) {
                    arr_type_cnt.push(str_type);
                }
            }
        }
    }
    // 卡类型为未定义卡
    if (0 === arr_type_cnt.length) {
        return 0;
    }
    var obj_recvcard_msg = {
        recvcard_num: ui_total_cnt,
        recvcard_type: arr_type_cnt
    };

    return obj_recvcard_msg;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    数据数组字段添加/更改
 * 参数:
 *    @param { Promise<Object> } obj_data 修改的数据对象
 *    @param { Promise<String> } str_name 修改或添加的字段name
 *     @param { Promise<Any> } data_val 修改或添加的数据值
 * 返回：
 *    @return { Promise<Object> }
 *      false 参数有误
 *      obj_data 修改后的数据对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.21
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_modify_card_data(obj_data, str_name, data_val) {
    if ("object" !== typeof obj_data || "string" !== typeof str_name || 0 === str_name.length) {
        return false;
    }
    if (obj_data[str_name]) {
        obj_data[str_name].push(data_val);
    } else {
        obj_data[str_name] = [data_val];
    }
    return obj_data;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    修改顶层 G_OBJ_WINDOW_DATA 数据
 * 参数:
 *    @param { Promise<String> } str_key key
 *    @param { Promise<String> } str_val val
 *    @param { Promise<String> } str_param_key 可为空 若存在则为修改G_OBJ_WINDOW_DATA中key数据对象的str_param_key对象下的str_val值
 * 备注:
 *    传入参数三如: G_OBJ_WINDOW_DATA.S0.child_num = G_OBJ_WINDOW_DATA.str_key.str_param_key = str_val
 * 返回：
 *    @return { Promise<Object> }
 *      false 参数有误
 *      obj_data 修改后的数据对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.25
 *      内容 : 所有代码
 ************************************************************************************************/
function update_g_obj_window_data(str_key, str_val, str_param_key) {
    if ("string" !== typeof str_key || 0 === str_key.length) {
        return false;
    }
    var obj_data = mc_get_top_data("G_OBJ_WINDOW_DATA");

    if (obj_data) {
        if ("string" === typeof str_param_key && 0 !== str_param_key.length) {
            if ("number" === typeof obj_data[str_key][str_param_key]) {
                obj_data[str_key][str_param_key] = str_val;
            }
        } else {
            obj_data[str_key] = str_val;
        }
        mc_set_top_data("G_OBJ_WINDOW_DATA", obj_data);
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    删除PORT/CARD 更新数据及页面显示
 * 参数:
 *    @param { Promise<String> } str_port_name port name
 *    @param { Promise<String> } str_card_name card name
 *    @param { Promise<Number> } ui_port_idx port index
 *    @param { Promise<String> } str_delect_type 删除类型 _P/S/_H
 * 备注:
 *    删除PORT:
 *    修改此PORT 所在卡数据 child_num、child_type、recvcard_type字段
 *    此PORT 下卡数据全部删除
 *    此PORT 之后PORT数据往前移
 *    PORT页面显示及元素标识修改(port_name、idx)
 *    删除CARD:
 *    修改此卡 所在PORT数据 child_num、child_type、hubport_num字段
 *    此卡 之后卡数据往前移
 *    卡页面显示及元素标识修改(card_name、port_name)
 * 返回：
 *    @return { Promise<Boolean> }
 *      false 参数有误
 *      true 更新成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_delect_port_data(str_port_name, str_card_name, ui_port_idx, str_delect_type) {
    if ("string" !== typeof str_port_name || 0 === str_port_name.length) {
        return false;
    }
    if ("string" !== typeof str_card_name) {
        return false;
    }
    if ("number" !== typeof ui_port_idx) {
        return false;
    }
    // 更新编辑框数据
    var obj_update_data = {};
    var obj_update_edit = {};
    var obj_data = mc_get_top_data("G_OBJ_WINDOW_DATA");
    var arr_keys = Object.keys(obj_data);
    var ui_cnt = str_port_name.length;
    var str_next = str_card_name + str_delect_type;
    var arr_recvcard_name = [];

    // 修改卡数据
    obj_data[str_card_name] = mc_update_card_data(obj_data[str_card_name], ui_port_idx);
    // 删除移动相关数据
    for (var idx = 0; idx < arr_keys.length; idx++) {
        var str_key = arr_keys[idx];

        // 只添加不匹配数据
        if (str_port_name !== str_key.substr(0, ui_cnt) && "object" === typeof obj_data[str_key]) {
            // 当前删除位置同级索引 如删除S0_P0 则S0_P1_R0 -> 1
            var ui_item_idx = Number(str_key.substring(str_next.length).split("_")[0]);

            // 此port下同级数据往前移
            if (str_next === str_key.substr(0, str_next.length) && ui_port_idx < ui_item_idx) {
                var str_update_name = str_next + (ui_item_idx - 1) + str_key.substr(str_next.length + 1);
                var str_type = str_key.substr(str_key.lastIndexOf("_") + 1, 1);
                var ui_index = Number(obj_data[str_key].index) - 1;
                var obj_edit_box = $("div[port_name='" + str_key + "']");

                // 保存原先name -> 初始请求参数
                if (!obj_data[str_key].origin_name) {
                    var str_origin_name = "origin_name";

                    obj_data[str_key][str_origin_name] = obj_data[str_key].name;
                }
                // 更新数据name
                obj_data[str_key].name = str_update_name;

                // 更新数据修改页面显示及元素标识
                if ("_P" === str_delect_type) {
                    // delete port
                    // 更新port索引
                    if ("P" === str_type && "_P" === str_delect_type) {
                        obj_data[str_key].index = ui_index;
                    }
                    // 更新接收卡name
                    if ("R" === str_type) {
                        arr_recvcard_name.push(str_update_name);
                    }
                    // 页面显示
                    if (0 !== obj_edit_box.length) {
                        obj_edit_box.attr("port_name", str_update_name);
                        obj_edit_box.attr("idx", ui_index);
                        obj_edit_box.children(".port_tip").children().eq(0).text("P" + (ui_index + 1));
                    }
                } else {
                    // delete card
                    var obj_card_box = $("div[card_name='" + str_key + "']");

                    if (0 !== obj_card_box.length) {
                        obj_data[str_key].index = ui_index;
                        obj_card_box.attr("card_name", str_update_name);
                        obj_card_box.children(".mc_card").children(".card_tip").children(".card_name").text(str_delect_type[str_delect_type.length - 1] + (ui_index + 1));
                    }
                    if (0 !== obj_edit_box.length) {
                        obj_edit_box.attr("port_name", str_update_name);
                    }
                }
                // 添加此数据
                obj_update_data[str_update_name] = obj_data[str_key];
            } else {
                obj_update_data[str_key] = obj_data[str_key];
            }
            obj_update_edit[str_key] = obj_edit_control[str_key];
        }
    }
    // 更新此卡recvcard_name字段
    if (0 !== arr_recvcard_name.length && obj_update_data[str_card_name].recvcard_name) {
        obj_update_data[str_card_name].recvcard_name = arr_recvcard_name;
    }
    obj_edit_control = obj_update_edit;
    // 设置数据
    mc_set_top_data("G_OBJ_WINDOW_DATA", obj_update_data);
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    修改卡数据
 * 参数:
 *    @param { Promise<Object> } obj_card_data 卡数据
 *    @param { Promise<Number> } ui_port_idx 当前删除项索引
 * 返回：
 *    @return { Promise<Object> }
 *      false 参数有误
 *      obj_data 修改后的数据对象
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.26
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_card_data(obj_card_data, ui_port_idx) {
    if ("object" !== typeof obj_card_data || "number" !== typeof ui_port_idx) {
        return false;
    }
    if (obj_card_data) {
        var ui_child_cnt = Number(obj_card_data.child_num) - 1;
        var arr_recvcard_type = obj_card_data.recvcard_type;
        var arr_hubport_num = obj_card_data.hubport_num;

        // child_num、child_type
        obj_card_data.child_num = ui_child_cnt;
        if (0 === ui_child_cnt) {
            obj_card_data.child_type = "CHILD";
        }
        // recvcard_type
        if (arr_recvcard_type) {
            arr_recvcard_type.splice(ui_port_idx, 1);
            obj_card_data.recvcard_type = arr_recvcard_type;
        }
        // hubport_num
        if (arr_hubport_num) {
            arr_hubport_num.splice(ui_port_idx, 1);
            obj_card_data.hubport_num = arr_hubport_num;
        }
    }
    return obj_card_data;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    PORT变化修改CARD数据及页面显示
 * 参数:
 *    @param { Promise<String> } str_card_name 当前CRAD NAME
 *    @param { Promise<Boolean> } b_unset_date true == 不更新数据 可为空
 * 返回：
 *    @return { Promise<Boolean> }
 *     true 修改成功
 *     false 参数有误
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.26
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_card_show(str_card_name, b_unset_date) {
    if ("string" !== typeof str_card_name || 0 === str_card_name.length) {
        return false;
    }
    var obj_data = mc_get_top_data("G_OBJ_WINDOW_DATA");
    var str_img_rect = mc_get_port_img_rect(str_card_name, obj_data);
    var str_sendcard_img = mc_basis_output_get_img(str_img_rect);

    if ("string" === typeof str_sendcard_img) {
        var arr_sendcard_img = mc_fm_img_rece(str_sendcard_img);
        var obj_card_box = $("div[card_name='" + str_card_name + "']").children(0).children(0);
        var obj_size = obj_card_box.children(".card_size");
        var obj_pot = obj_card_box.children(".card_pot");
        var obj_card_data = obj_data[str_card_name];

        // 修改卡显示数据
        obj_pot.children(".left").text(arr_sendcard_img[0]);
        obj_pot.children(".top").text(arr_sendcard_img[1]);
        obj_size.children(".width").text(arr_sendcard_img[2]);
        obj_size.children(".height").text(arr_sendcard_img[3]);
        if (!b_unset_date) {
            // 修改卡数据
            obj_card_data.left = arr_sendcard_img[0];
            obj_card_data.top = arr_sendcard_img[1];
            obj_card_data.width = arr_sendcard_img[2];
            obj_card_data.height = arr_sendcard_img[3];
        }
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取数据 origin_name
 * 参数:
 *    @param { Promise<String> } str_name 数据key
 * 返回：
 *    @return { Promise<String> }
 *     string origin_name
 *     false 参数有误/无原始name
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.8.28
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_origin_name(str_name) {
    if ("string" !== typeof str_name || 0 === str_name.length) {
        return false;
    }
    var obj_data = mc_get_top_data("G_OBJ_WINDOW_DATA");

    if (!obj_data) {
        return false;
    }
    if (obj_data[str_name]) {
        if (obj_data[str_name].origin_name) {
            return obj_data[str_name].origin_name;
        }
    }
    return false;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    更新输入/输出口数据 更新页面输入框显示  ---重置端口
 * 参数:
 *    @param { Promise<Object> } obj_data 更改数据源
 *    @param { Promise<Object> } obj_update_data 最新设置数据
 *    @param { Promise<String> } str_name 数据key
 *    @param { Promise<Boolean> } b_unset_edit true == 不设置页面显示  可为空
 * 返回：
 *    @return { Promise<String> }
 *     true 更新成功
 *     false 参数有误
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.01.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_port_data(obj_data, obj_update_data, str_name, b_unset_edit) {
    if ("object" !== typeof obj_data || "object" !== typeof obj_update_data) {
        return false;
    }
    var obj_edit = obj_edit_control[str_name];
    var str_width = String(obj_update_data.width);
    var str_height = String(obj_update_data.height);
    var str_left = String(obj_update_data.left);
    var str_top = String(obj_update_data.top);

    obj_data.width = str_width;
    obj_data.height = str_height;
    obj_data.left = str_left;
    obj_data.top = str_top;

    if ("object" === typeof obj_edit && !b_unset_edit) {
        obj_edit.width.set_dom_val(str_width);
        obj_edit.height.set_dom_val(str_height);
        obj_edit.left.set_dom_val(str_left);
        obj_edit.top.set_dom_val(str_top);
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    构建HUB输出端口发送数据  ---重置下发
 * 参数:
 *    @param { Promise<String> } str_name portname
 *    @param { Promise<Object> } obj_data window data
 *    @param { Promise<Object> } obj_update_data update data {left:"",top:"",width:"",height:""}
 *    @param { Promise<Array> } arr_hubport_img save date [{str_port_name:"", str_img:""},,]
 * 返回：
 *    @return { Promise<Array> }
 *     arr_hubport_img :save data
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.01
 *      内容 : 所有代码
 ************************************************************************************************/
// function mc_create_hubport_req_data(str_name, obj_data, obj_update_data, arr_hubport_img) {
//     if ("[object String]" !== Object.prototype.toString.call(str_name) || 0 === str_name.length) {
//         return arr_hubport_img;
//     }
//     if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
//         return arr_hubport_img;
//     }
//     if ("[object Object]" !== Object.prototype.toString.call(obj_update_data)) {
//         return arr_hubport_img;
//     }
//     if ("[object Array]" !== Object.prototype.toString.call(arr_hubport_img)) {
//         return arr_hubport_img;
//     }
//     // check：是否为发送卡端口
//     if (2 !== str_name.split("_").length) {
//         return false;
//     }
//     var obj_port_data = obj_data[str_name];

//     // check：此端口下子卡类型为HUB
//     if ("HUB" !== obj_port_data.child_type) {
//         return false;
//     }
//     // check：HUB数据存在
//     if (obj_data[str_name + "_H0"]) {
//         return false;
//     }
//     // create hub data
//     var ui_hub_cnt = obj_port_data.child_num;
//     var arr_hub_port_cnt = obj_port_data.hubport_num;
//     var str_img = "";

//     for (var hub_cnt = 0; hub_cnt < ui_hub_cnt; hub_cnt++) {
//         var obj_hubport_img = new format_hubport_data();
//         var str_hub_name = str_name + "_H" + hub_cnt;
//         var ui_hubport_cnt = Number(arr_hub_port_cnt[hub_cnt]);

//         // hubport data
//         str_img = mc_create_hubport_data(obj_update_data, ui_hubport_cnt);
//         obj_hubport_img.str_hub_name = str_hub_name;
//         obj_hubport_img.str_img = str_img;
//         arr_hubport_img.push(obj_hubport_img);
//     }
//     return arr_hubport_img;
// }

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    构建HUB输出端口发送数据格式  ---重置下发
 * 参数:
 *    无
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.01
 *      内容 : 所有代码
 ************************************************************************************************/
function format_hubport_data() {
    this.str_hub_name = "";
    this.str_img = "";
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取HUB BACKUP 请求JSON字串
 * 参数:
 *    @param { Promise<String> } str_param "0:0" 到PORT PARAM
 *    @param { Promise<Number> } ui_cnt 需请求HUB数量
 *    @param { Promise<String> } str_port_name 上层PORT NAME "S0_P0"
 * 返回：
 *    @return { Promise<object> }
 *     {} 参数有误
 *     {str_json:"请求字串", arr_key:[对应获取数据key]}
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.04.23
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_hubbackup_require_strjson(str_param, ui_cnt, str_port_name) {
    if ("[object String]" !== Object.prototype.toString.call(str_param) ||
        "[object Number]" !== Object.prototype.toString.call(ui_cnt) ||
        "[object String]" !== Object.prototype.toString.call(str_port_name)) {
        return {};
    }
    var arr_key = [];
    var obj_sdk_param = new mc_sdk_param();

    str_param = "(" + str_param + ":";
    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PAPAM");
    obj_sdk_param.set_func("HW_HUBCARD_BACKUP");
    for (var i = 0; i < ui_cnt; i++) {
        var s_param = str_param + i + ")";

        arr_key.push({
            str_param: s_param,
            card_name: str_port_name + "_H" + i
        });
        obj_sdk_param.set_param_value(s_param, "");
    }
    return {
        str_json: obj_sdk_param.get_json(),
        arr_key: arr_key
    };
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    跳转HUB 更新其backup值
 * 参数:
 *    @param { Promise<Array> } arr_key {str_param:"",card_name:""}
 *    @param { Promise<String> } str_json 请求HUB BACKUP 回调数据
 * 返回：
 *    @return { Promise<object> }
 *     false 参数有误
 *     true 更新成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.04.23
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_jump_update_hubbackup(arr_key, str_json) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_key) || "[object String]" !== Object.prototype.toString.call(str_json)) {
        return false;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_json(str_json);
    for (var i = 0; i < arr_key.length; i++) {
        var obj_data = arr_key[i];
        var str_update_backup = obj_sdk_param.get_param_value(obj_data.str_param);
        var obj_hub_data = parent.G_OBJ_WINDOW_DATA[obj_data.card_name];

        if (("0" === str_update_backup || "1" === str_update_backup) && obj_hub_data) {
            obj_hub_data.backup = str_update_backup;
        }
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取PORT 导航值 ---- 跳转HUB时
 * 参数:
 *    @param { Promise<Object> } obj_data window data
 *    @param { Promise<String> } str_card_name sendcard name
 * 返回：
 *    @return { Promise<object> }
 *     false 参数有误
 *     true 更新成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.04.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_port_radio(obj_data, str_card_name) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_data) || "[object String]" !== Object.prototype.toString.call(str_card_name)) {
        return [];
    }
    var obj_card_data = obj_data[str_card_name];

    if (obj_card_data && obj_card_data.child_num) {
        var arr_port = [];

        for (var idx = 0; idx < Number(obj_card_data.child_num); idx++) {
            arr_port.push("P" + (idx + 1));
        }
        return arr_port;
    }
    return [];
}


// 发送卡输出端口备份数据处理---
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    创建HUBPORT图像偏移字串  ---重置下发
 * 参数:
 *    @param { Promise<Object> } obj_data update data {left:"",top:"",width:"",height:""}
 *    @param { Promise<Number> } ui_cnt hubport cnt
 * 返回：
 *    @return { Promise<String> }
 *     HUBPORT图像偏移字串 (X:Y:W:H),,
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.01
 *      内容 : 所有代码
 ************************************************************************************************/
// function mc_create_hubport_data(obj_data, ui_cnt) {
//     if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
//         return "";
//     }
//     if ("[object Number]" !== Object.prototype.toString.call(ui_cnt)) {
//         return "";
//     }
//     var str_l = obj_data.left;
//     var str_t = obj_data.top;
//     var str_w = obj_data.width;
//     var str_h = obj_data.height;
//     var str_img = "";

//     for (var idx = 0; idx < ui_cnt; idx++) {
//         var str_item_img = "(" + str_l + ":" + str_t + ":" + str_w + ":" + str_h + ")";

//         str_img += str_item_img + ",";
//     }
//     return str_img.substr(0, str_img.lastIndexOf(","));
// }

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取发送卡PORT口备份标识
 * 参数:
 *    @param { Promise<String> } str_json 请求返回json
 * 返回：
 *    @return { Promise<Array> }
 *     PORT口备份标识
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.05
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_sendport_backup_data(str_json) {
    if ("[object String]" !== Object.prototype.toString.call(str_json)) {
        return [];
    }
    var obj_sdk_param = new mc_sdk_param();
    var arr_backup_data = [];

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_json(str_json);
    var ui_port_cnt = obj_sdk_param.get_param_cnt();

    for (var i = 0; i < ui_port_cnt; i++) {
        var str_param_name = obj_sdk_param.get_param_name(i);

        if ("ERROR_CODE" !== str_param_name) {
            var idx = str_param_name.substr(str_param_name.lastIndexOf(":") + 1).split(")")[0];

            arr_backup_data[Number(idx)] = obj_sdk_param.get_param_value(str_param_name);
        }
    }
    return arr_backup_data;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取指定发送卡PORT口备份标识
 * 参数:
 *    @param { Promise<Array> } arr_backup_data 备份标识数组
 *    @param { Promise<String> } ui_port_idx port下标
 * 返回：
 *    @return { Promise<String> }
 *     PORT口备份标识 参数有误/数据有误返回"1"
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.05
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_sendport_backup_item(arr_backup_data, ui_port_idx) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_backup_data) || "[object Number]" !== Object.prototype.toString.call(ui_port_idx)) {
        return "1";
    }
    var str_backup = arr_backup_data[ui_port_idx];

    if ("0" !== str_backup && "1" !== str_backup) {
        return "1";
    }
    return str_backup;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    切换SENDPORT备份数据 ---对照转变其余PORT口数据
 *      1. 更新PORT数据 X Y W H
 *      2. 更新备份标识 backup
 * 参数:
 *    @param { Promise<String> } str_port_name PORT NAME
 *    @param { Promise<String> } str_main_port_name 对照PORT NAME
 *    @param { Promise<String> } str_main_idx 对照PORT 下标
 * 返回：
 *    @return { Promise<String> }
 *     PORT口备份标识 参数有误/数据有误返回"1"
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.02.05
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_backup_data(str_port_name, str_main_port_name, str_main_idx) {
    if ("[object String]" !== Object.prototype.toString.call(str_port_name)) {
        return false;
    }
    if ("[object String]" !== Object.prototype.toString.call(str_main_port_name)) {
        return false;
    }
    var obj_window_data = parent.G_OBJ_WINDOW_DATA;
    var obj_port_data = obj_window_data[str_port_name];
    var obj_main_port = obj_window_data[str_main_port_name];

    if (!obj_port_data) {
        return false;
    }
    // 是否切换本身 false==切换本身
    var b_unitself = true;
    // 辅
    var str_backup = "0";

    if (str_main_idx === String(obj_port_data.index)) {
        b_unitself = false;
        // 主
        str_backup = "1";
    }
    // 无对照项 更新输入框数据为当前PORT下标
    if (!obj_main_port) {
        var obj_edit = obj_edit_control[str_port_name];

        if (obj_edit && obj_edit.backup) {
            obj_edit.backup.set_dom_val(String(Number(obj_port_data.index) + 1));
        }
    }
    if (b_unitself) {
        // 更新选中PORT数据及页面显示
        mc_update_port_data(obj_port_data, obj_main_port, str_port_name);
    }

    // 更新backup 状态
    obj_port_data.backup = str_backup;
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *   切换SENDPORT备份数据
 *   切换HUB备份数据
 * 参数:
 *    @param { Promise<String> } str_port_name PORT NAME
 *    @param { Promise<String> } str_backup 备份信息 "0"(备) "1"(主)
 *    @param { Promise<Boolean> } b_update_page_show 是否更新页面显示 可为空 默认不更新
 * 返回：
 *    @return { Promise<Boolean> }
 *     true 切换成功
 *     false 参数有误/数据不存在
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.01
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_backup_checkbox_data(str_port_name, str_backup) {
    if ("[object String]" !== Object.prototype.toString.call(str_port_name)) {
        return false;
    }
    if ("0" !== str_backup && "1" !== str_backup) {
        return false;
    }
    var obj_window_data = parent.G_OBJ_WINDOW_DATA;
    var obj_port_data = obj_window_data[str_port_name];

    if ("[object Object]" !== Object.prototype.toString.call(obj_port_data)) {
        return false;
    }
    // 更新选中PORT数据 backup 状态
    obj_port_data.backup = str_backup;

    // 更新选中PORT下HUB数据 backup 状态
    // 不修改HUB
    // if ("HUB" === obj_port_data.child_type) {
    //     var ui_hub_cut = 0;

    //     while (ui_hub_cut < Number(obj_port_data.child_num)) {
    //         var obj_hub_data = obj_window_data[str_port_name + "_H" + ui_hub_cut];

    //         if ("[object Object]" === Object.prototype.toString.call(obj_hub_data)) {
    //             obj_hub_data.backup = str_backup;
    //         }
    //         ui_hub_cut += 1;
    //     }
    // }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取当前筛选卡name数组 发送卡PORT允许发送备份口下标数组
 * 参数:
 *    @param { Promise<String> } str_param 卡下标 sendcard:sendport / sendcard:sendport:hubcard
 *    @param { Promise<Object> } obj_data 卡数据
 * 返回：
 *    @return { Promise<Boolean> }
 *     {
 *       arr_card_name: arr_sendcard_name+arr_hubcard_name,
 *       sendport_idx: sendport_idx
 *     }
 *     null 参数有误/数据不存在
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_arr_cardname(str_param, obj_data) {
    if ("[object String]" !== Object.prototype.toString.call(str_param)) {
        return null;
    }
    if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
        return null;
    }
    var arr_param = str_param.trim().split(":");
    var len = arr_param.length;
    var arr_key = Object.keys(obj_data);

    // 至少存在发送卡PORT标识 至多到HUB卡标识 无卡数据
    if (1 > len || 3 < len || 0 === arr_key.length) {
        return null;
    }
    var arr_sendcard_name = [];
    var arr_hubcard_name = [];
    var sendport_idx = {};

    for (var i = 0; i < arr_key.length; i++) {
        var element = arr_key[i];

        var ui_param_cnt = element.split("_").length;

        if (1 === ui_param_cnt) {
            arr_sendcard_name.push(element);
        }
        if (2 === ui_param_cnt) {
            var ui_port_idx = Number(element.substr(element.lastIndexOf("_") + 2));

            sendport_idx[ui_port_idx] = sendport_idx[ui_port_idx] ? 1 : ui_port_idx;
        }
        if (3 === ui_param_cnt) {
            arr_hubcard_name.push(element);
        }
    }
    sendport_idx = Object.keys(sendport_idx);
    if (arr_param[2] && -1 !== Number(arr_param[2])) {
        arr_hubcard_name = mc_filter_tool(function (item) {
            return item.substr(item.lastIndexOf("_") + 2) === arr_param[2];
        }, arr_hubcard_name);
    }
    if (arr_param[1] && -1 !== Number(arr_param[1])) {
        sendport_idx = mc_filter_tool(function (item) {
            return item === arr_param[1];
        }, sendport_idx);
        arr_hubcard_name = mc_filter_tool(function (item) {
            return item.split("_")[1].slice(1) === arr_param[1];
        }, arr_hubcard_name);
    }
    if (arr_param[0] && -1 !== Number(arr_param[0])) {
        arr_sendcard_name = mc_filter_tool(function (item) {
            return item.substr(item.lastIndexOf("_") + 2) === arr_param[0];
        }, arr_sendcard_name);
        arr_hubcard_name = mc_filter_tool(function (item) {
            return item.split("_")[0].slice(1) === arr_param[0];
        }, arr_hubcard_name);
    }
    return {
        arr_card_name: arr_sendcard_name.concat(arr_hubcard_name),
        sendport_idx: sendport_idx
    };
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取当前允许发送备份信息PORT/CARD NAME
 * 参数:
 *    @param { Promise<Array> } arr_card_name 允许所有发送 卡
 *    @param { Promise<Array> } arr_sendport_idx 允许发送PORT口索引
 *    @param { Promise<Boolean> } b_check_hub 是否需要检查构造HUB卡数据 ture不检查 可为空'
 *    @param { Promise<Function> } fn_callback 回调函数
 * 返回：
 *    @return { Promise<Object> }
 *     {
 *       arr_sendcard_port: arr_sendcard_port,
 *       arr_hubcard_name: arr_hubcard_name
 *       }
 *     null 参数有误/数据不存在
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_backup_name(arr_card_name, arr_sendport_idx, b_check_hub, fn_callback) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_card_name) || 0 === arr_card_name.length) {
        return null;
    }
    var arr_sendcard_name = [];
    var arr_hubcard_name = [];

    for (var i = 0; i < arr_card_name.length; i++) {
        var str_name = arr_card_name[i];

        // 可能存在备份网口创建的临时数据 添加backup字段 === 其PORT口backup
        if ("[object Object]" === Object.prototype.toString.call(str_name) && str_name.str_hub_name) {
            var str_hub_name = str_name.str_hub_name;

            str_name.backup = parent.G_OBJ_WINDOW_DATA[str_hub_name.substr(0, str_hub_name.lastIndexOf("_"))].backup;
            arr_hubcard_name.push(str_name);
            continue;
        }
        if (1 === str_name.split("_").length) {
            arr_sendcard_name.push(str_name);
        } else {
            arr_hubcard_name.push(str_name);
        }
    }
    var arr_sendcard_port = [];


    for (var idx = 0; idx < arr_sendcard_name.length; idx++) {
        var str_sendcard_name = arr_sendcard_name[idx];

        if (parent.G_OBJ_WINDOW_DATA[str_sendcard_name]) {
            var ui_cnt = Number(parent.G_OBJ_WINDOW_DATA[str_sendcard_name].child_num);
            var index = 0;

            while (index < ui_cnt) {
                if (judge_port(index)) {
                    arr_sendcard_port.push(str_sendcard_name + "_P" + index);
                }
                index += 1;
            }
        }
    }

    // 检验sendport下子卡为HUB数据是否被构造 若无请求构造
    if (!b_check_hub) {
        mc_check_create_hub_data(arr_sendcard_port, function (arr_data) {
            if ("[object Array]" === Object.prototype.toString.call(arr_data)) {
                fn_callback({
                    arr_sendcard_port: arr_sendcard_port,
                    arr_hubcard_name: arr_hubcard_name.concat(arr_data),
                    arr_card_name: arr_card_name.concat(arr_data)
                });
            }
        });
    } else {
        fn_callback({
            arr_sendcard_port: arr_sendcard_port,
            arr_hubcard_name: arr_hubcard_name,
            arr_card_name: arr_card_name
        });
    }
    return true;
    function judge_port(ui_index) {
        if (!arr_sendport_idx) {
            return true;
        }
        for (var z = 0; z < arr_sendport_idx.length; z++) {
            if (Number(arr_sendport_idx[z]) === ui_index) {
                return true;
            }
        }
        return false;
    }
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    检验sendport下 子卡为HUB 数据是否被构造 若无请求构造
 * 参数:
 *    @param { Promise<Array> } arr_sendcard_port SENDPORT NAME 数组
 *    @param { Promise<Function> } fn_callback 回调函数
 *    @param { Promise<Object> } obj_port_data 重置网口时传递 处理未请求创建HUB卡情况 可为空 {width:,heigrh:,left:,top:,}
 * 返回：
 *    null
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_check_create_hub_data(arr_sendcard_port, fn_callback, obj_port_data) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_sendcard_port) || 0 === arr_sendcard_port.length) {
        fn_callback([]);
        return;
    }
    var obj_data = parent.G_OBJ_WINDOW_DATA;
    // 需要请求构造HUB数据PARAM
    var obj_hub_param = {};
    // 返回构造HUB卡NAME
    var arr_hub_name = [];

    // 1. 检索需要构造HUB参数
    for (var idx = 0; idx < arr_sendcard_port.length; idx++) {
        var str_port = arr_sendcard_port[idx];

        if (obj_data[str_port] && "HUB" === obj_data[str_port].child_type) {
            var ui_hub_cnt = Number(obj_data[str_port].child_num);
            var index = 0;

            while (index < ui_hub_cnt) {
                var str_hub_name = str_port + "_H" + index;

                if (!obj_data[str_hub_name]) {
                    obj_hub_param[mc_get_data_param(str_hub_name, 0)[0]] = {
                        str_port_name: str_port,
                        str_hub_name: str_hub_name
                    };
                    arr_hub_name.push(str_hub_name);
                }
                index += 1;
            }
        }
    }

    // 2. 获取HUB输出端口图像数据、HUBPORT上接收卡连接状态 处理保存数据
    mc_get_hub_and_hubport_data(obj_hub_param, obj_data, function (b_success) {
        if (b_success) {
            fn_callback(arr_hub_name);
            return;
        }
        fn_callback([]);
        return;
    }, false, obj_port_data);

    return;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    群发获取HUB卡数据
 *    1. 获取HUB卡输出端口图像信息 request cnt 1
 *    2. 获取HUBPORT下接收卡数量 request cnt 2
 *    3. 请求获取数据处理 更新窗口对象数据
 * 参数:
 *    @param { Promise<Object> } obj_hub_param HUB请求标识
 *    @param { Promise<Object> } obj_data 窗口数据 G_OBJ_WINDOW_DATA
 *    @param { Promise<Function> } fn_callback 回调函数
 *    @param { Promise<Boolean> } b_create_hubcard 是否创建HUB卡(创建HUB卡时 获取HUB备份信息，用于页面显示) 可为空 默认不创建
 *    @param { Promise<Object> } o_hubport_data 重置网口时传递 处理未请求创建HUB卡情况 可为空 {width:,heigrh:,left:,top:,}
 * 备注：
 *      参数一
 *      {
 *          "0:0:0":{
 *              str_hub_name: "S0_P0_H0"
 *              str_port_name: "S0_P0"
 *          },,
 *      }
 * 返回：
 *    null
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_hub_and_hubport_data(obj_hub_param, obj_data, fn_callback, b_create_hubcard, o_hubport_data) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_hub_param) || "[object Object]" !== Object.prototype.toString.call(obj_data)) {
        fn_callback(false);
        return;
    }
    if ("[object Function]" !== Object.prototype.toString.call(fn_callback)) {
        fn_callback(false);
        return;
    }
    var arr_hub_param = Object.keys(obj_hub_param);
    var ui_hub_len = arr_hub_param.length;

    if (0 === ui_hub_len) {
        fn_callback(false);
        return;
    }

    // 构建请求字串
    // 获取HUB输出口图像
    var obj_sdk_param = new mc_sdk_param();
    // 获取接收卡连接状态
    var obj_hubport_sdk_param = new mc_sdk_param();
    // 获取HUB卡备份信息
    var obj_hubcard_backup_sdk_param = new mc_sdk_param();
    var arr_hub_backup_data = [];
    var obj_hubport_param = {};

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_func("HW_HUBCARD_OUTPORT_IMG_RECT");

    obj_hubport_sdk_param.set_param_clear();
    obj_hubport_sdk_param.set_cmd("GET_PARAM");
    obj_hubport_sdk_param.set_func("HW_RECVCARD_CONNECT");

    obj_hubcard_backup_sdk_param.set_param_clear();

    for (var idx = 0; idx < arr_hub_param.length; idx++) {
        var str_param = "(" + arr_hub_param[idx] + ")";

        obj_sdk_param.set_param_value(str_param, "");
        obj_hubcard_backup_sdk_param.set_param_value(str_param, "");
        arr_hub_backup_data.push("1");
    }

    // 只获取HUB备份信息及子卡连接状态
    // 重置网口时
    if (o_hubport_data) {
        // REQUEST HUBCARD BACKUP
        mc_get_hubcard_backup(obj_hubcard_backup_sdk_param.get_json(), function (result_backup) {
            if ("[object String]" === Object.prototype.toString.call(result_backup) && 0 !== result_backup.length) {
                obj_hubcard_backup_sdk_param.set_param_clear();
                obj_hubcard_backup_sdk_param.set_json(result_backup);

                for (var z = 0; z < ui_hub_len; z++) {
                    var str_backup = obj_hubcard_backup_sdk_param.get_param_value("(" + arr_hub_param[z] + ")");

                    if ("0" === str_backup) {
                        arr_hub_backup_data[z] = str_backup;
                    }
                }
            }
            create_hubport_data();
        });
        return;
    }

    // REQUEST HUBPORT IMG
    mc_get_hubcard_outport_img_rect("1", function (result) {
        obj_sdk_param.set_param_clear();
        obj_sdk_param.set_json(result);

        if (b_create_hubcard) {
            // REQUEST HUBCARD BACKUP
            mc_get_hubcard_backup(obj_hubcard_backup_sdk_param.get_json(), function (result_backup) {
                if ("[object String]" === Object.prototype.toString.call(result_backup) && 0 !== result_backup.length) {
                    obj_hubcard_backup_sdk_param.set_param_clear();
                    obj_hubcard_backup_sdk_param.set_json(result_backup);

                    for (var z = 0; z < ui_hub_len; z++) {
                        var str_backup = obj_hubcard_backup_sdk_param.get_param_value("(" + arr_hub_param[z] + ")");

                        if ("0" === str_backup) {
                            arr_hub_backup_data[z] = str_backup;
                        }
                    }
                }
                create_hubport_data();
            });
            return;
        }
        create_hubport_data();
    }, obj_sdk_param.get_json());

    function create_hubport_data() {
        for (var i = 0; i < ui_hub_len; i++) {
            handle_hub_data(i);
        }
        // REQUEST HUBPORT RECVCARD CONNECT
        mc_get_recvcard_connect("1", function (result) {
            var arr_hubport_param = Object.keys(obj_hubport_param);

            // 记录HUBPORT数据
            obj_hubport_sdk_param.set_param_clear();
            obj_hubport_sdk_param.set_json(result);
            for (var j = 0; j < arr_hubport_param.length; j++) {
                handle_hubport_data(j, arr_hubport_param[j]);
            }
            fn_callback(true);
        }, obj_hubport_sdk_param.get_json());
    }
    return;

    // 保存HUB数据
    function handle_hub_data(ui_idx) {
        // 记录HUB数据
        var str_param_key = arr_hub_param[ui_idx];
        var str_default = "(0:0:1:1),";
        var str_img = "";
        // HUB卡输出端口图像信息

        if (!o_hubport_data) {
            str_img = obj_sdk_param.get_param_value("(" + str_param_key + ")");
        } else {
            str_default = "(" + o_hubport_data.left + ":" + o_hubport_data.top + ":" + o_hubport_data.width + ":" + o_hubport_data.height + "),";
        }
        var obj_port_data = obj_data[obj_hub_param[str_param_key].str_port_name];
        // hubport数量
        var child_num = 0;
        var ui_child_idx = 0;
        var str_name = obj_hub_param[str_param_key].str_hub_name;

        if (obj_port_data) {
            child_num = Number(obj_port_data.hubport_num[Number(str_name.substr(str_name.lastIndexOf("_") + 2))]);
        }
        // 获取失败情况 HUB卡输出端口数据为空
        if (0 === str_img.length) {
            for (var i = 0; i < child_num; i++) {
                str_img += str_default;
            }
            str_img = str_img.replace(/,$/gi, "");
        }
        // HUB卡图像区域(X:Y:W:H)
        var str_data = mc_basis_output_get_img(str_img);
        var obj_param = mc_fm_data_create_param(str_data, str_name, ui_idx, child_num, "HUBPORT", "MC_LANG_HUB_CARD", obj_port_data.backup);
        var arr_data = str_img.split(",");

        // 记录HUB数据
        obj_data[str_name] = obj_param;
        if (b_create_hubcard) {
            // 记录HUB备份信息显示数据
            obj_data[str_name].backup = arr_hub_backup_data[ui_idx];
            // 创建HUB
            mc_create_card(obj_param);
        }
        // hubport 请求字串
        while (ui_child_idx < child_num) {
            obj_hubport_param[str_param_key + ui_child_idx] = {
                str_img: arr_data[ui_child_idx],
                str_hubport_name: str_name + "_P" + ui_child_idx,
                str_port_name: str_name
            };
            obj_hubport_sdk_param.set_param_value(str_param_key + ui_child_idx, "(" + str_param_key + ":" + ui_child_idx + ")");
            ui_child_idx += 1;
        }
        return true;
    }

    // 保存HUBPORT数据
    // 当前PORT索引 获取接收卡数量数据对应KEY
    function handle_hubport_data(ui_idx, str_key) {
        var str_recvcard_num = obj_hubport_sdk_param.get_attr_val(str_key, "STATUS");
        var obj_hubport_data = obj_hubport_param[str_key];
        var o_hubport_param = {};
        var s_hubport_name = obj_hubport_data.str_hubport_name;
        var str_name = obj_hubport_data.str_port_name;

        if ("[object String]" === Object.prototype.toString.call(str_recvcard_num) && 0 !== str_recvcard_num.length) {
            var obj_recvcard_type = mc_get_recvcard_msg(str_recvcard_num);
            var ui_recvcard_cnt = 0;
            var str_child_type = "";


            if ("object" !== typeof obj_recvcard_type) {
                str_child_type = "CHILD";
                obj_recvcard_type = 0;
            } else {
                ui_recvcard_cnt = Number(obj_recvcard_type.recvcard_num);
                str_child_type = "RECV";
            }

            if (!obj_hubport_data.str_img) {
                // 参数不够子窗口数量 创建默认
                o_hubport_param = mc_create_window_params(s_hubport_name, ui_idx, 0, "CHILD", "MC_LANG_OUTPORT");
            } else {
                o_hubport_param = mc_fm_data_create_param(obj_hubport_data.str_img, s_hubport_name, ui_idx, ui_recvcard_cnt, str_child_type, "MC_LANG_OUTPORT");
            }
            // HUB卡上记录recvcard_type数据
            obj_data[str_name] = mc_modify_card_data(obj_data[str_name], "recvcard_type", obj_recvcard_type);
        } else {
            if (!obj_hubport_data.str_img) {
                o_hubport_param = mc_create_window_params(s_hubport_name, ui_idx, 0, "CHILD", "MC_LANG_OUTPORT");
            } else {
                o_hubport_param = mc_fm_data_create_param(obj_hubport_data.str_img, s_hubport_name, ui_idx, 0, "CHILD", "MC_LANG_OUTPORT");
            }
        }
        // 存储HUBPORT数据
        obj_data[s_hubport_name] = o_hubport_param;
        if (b_create_hubcard) {
            // 创建HUBPORT
            mc_create_port(o_hubport_param, str_name);
            mc_select_first_port();
        }
        return true;
    }
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取 下发卡输出端口 请求参数数据
 * 参数:
 *    @param { Promise<String> } str_card_name 卡name
 * 返回：
 *    @return { Promise<Object> }
 *     {
 *       str_img_rect: str_img_rect, // 图像信息
 *       str_fun: str_fun, // set_func data
 *       str_param: str_param // param
 *   }
 *     null 参数有误/数据不存在
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_request_param(str_card_name) {
    var str_img_rect = "";
    var str_fun = "";
    var str_param = "";

    // 未构建数据HUB --->重置下发时构建的临时数据
    if ("[object Object]" === Object.prototype.toString.call(str_card_name)) {
        str_img_rect = str_card_name.str_img;
        str_card_name = str_card_name.str_hub_name;
    } else {
        str_img_rect = mc_get_port_img_rect(str_card_name, parent.G_OBJ_WINDOW_DATA);
    }
    // 重置网口 发送卡类型判断
    if (-1 !== str_card_name.indexOf("H")) {
        str_fun = "HW_HUBCARD_OUTPORT_IMG_RECT";
    } else {
        str_fun = "HW_SENDCARD_OUTPORT_IMG_RECT";
    }

    str_param = mc_get_data_param(str_card_name, 0)[0];

    if (-1 !== str_param.indexOf(":")) {
        str_param = "(" + str_param + ")";
    }
    return {
        str_img_rect: str_img_rect,
        str_fun: str_fun,
        str_param: str_param
    };
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    更新HUB BACKUP === 对应PORT BACKUP
 * 参数:
 *    @param { Promise<Array> } arr_hub_name HUB NAME
 *    @param { Promise<Object> } obj_data 窗口数据 G_OBJ_WINDOW_DATA
 * 返回：
 *    @return { Promise<Object> }
 *     false 参数有误
 *     true 更新成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.29
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_hub_backup(arr_hub_name, obj_data) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_hub_name) || 0 === arr_hub_name.length) {
        return false;
    }
    if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
        return false;
    }
    for (var i = 0; i < arr_hub_name.length; i++) {
        var str_hub_name = arr_hub_name[i];

        // 跳过重置网口临时数据情况
        if ("[object Object]" === Object.prototype.toString.call(str_hub_name)) {
            continue;
        }
        var str_port_name = str_hub_name.substr(0, str_hub_name.lastIndexOf("_"));

        if ("[object Object]" === Object.prototype.toString.call(obj_data[str_hub_name]) && "[object Object]" === Object.prototype.toString.call(obj_data[str_port_name])) {
            obj_data[str_hub_name].backup = obj_data[str_port_name].backup;
        }
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    修改备份更新页面显示
 * 参数:
 *    @param { Promise<Array> } arr_sendport_name SENDPORT NAME
 *    @param { Promise<Array> } arr_hubcard_name HUB NAME
 *    @param { Promise<Boolean> } b_backup ture 备份 === "0"
 * 返回：
 *    @return { Promise<Object> }
 *     false 参数有误
 *     true 更新成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.30
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_page_backup_show(arr_sendport_name, arr_hubcard_name, b_backup) {
    if ("[object Array]" !== Object.prototype.toString.call(arr_sendport_name) || "[object Boolean]" !== Object.prototype.toString.call(b_backup)) {
        return false;
    }
    if ("[object Array]" !== Object.prototype.toString.call(arr_hubcard_name)) {
        return false;
    }
    // 当前所在界面
    var str_lang = mc_get_crumb_lang_id().children("span").attr("lang_id");

    // SENDCARD
    if ("MC_LANG_BTN_SCREEN_SENDING_CARD" === str_lang) {
        for (var i = 0; i < arr_sendport_name.length; i++) {
            var obj_edit = obj_edit_control[arr_sendport_name[i]];

            // 获取对应checkbox控件对象
            if (obj_edit && obj_edit.backup) {
                obj_edit.backup.set_dom_val(b_backup);
            }
        }
    }

    // HUBCARD
    if ("MC_LANG_HUB_CARD" === str_lang) {
        for (var j = 0; j < arr_hubcard_name.length; j++) {
            var $obj_backup = $("div[backup_card_name='" + arr_hubcard_name[j] + "']");

            if ($obj_backup) {
                if (b_backup) {
                    $obj_backup.text(arr_edit_lang[4]).attr("backup", "0");
                } else {
                    $obj_backup.text(arr_edit_lang[5]).attr("backup", "1");
                }
            }
        }
    }
    return true;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取对应SENDPORT NAME 及 HUBNAME
 * 参数:
 *    @param { Promise<Object> } obj_data {arr_card_name:[], sendport_idx:[]}
 *    @param { Promise<Object> } obj_window_data HUB NAME
 * 返回：
 *    @return { Promise<Object> }
 *     null 参数有误
 *     {arr_sendport_name: [], arr_hubcard_name: []}
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.30
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_get_backup_name_data(obj_data, obj_window_data) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
        return null;
    }
    if ("[object Object]" !== Object.prototype.toString.call(obj_window_data)) {
        return null;
    }
    var arr_card_name = obj_data.arr_card_name;
    var arr_sendport_idx = obj_data.sendport_idx;
    var arr_sendport_name = [];
    var arr_hubcard_name = [];

    for (var i = 0; i < arr_card_name.length; i++) {
        var str_name = arr_card_name[i];

        if (-1 === str_name.indexOf("_")) {
            if (obj_window_data[str_name]) {
                var index = 0;

                while (index < arr_sendport_idx.length) {
                    arr_sendport_name.push(str_name + "_P" + arr_sendport_idx[index++]);
                }
            }
        } else {
            arr_hubcard_name.push(str_name);
        }
    }
    return {
        arr_sendport_name: arr_sendport_name,
        arr_hubcard_name: arr_hubcard_name
    };
}

//  --------------------------------------------数据处理 END------------------------------------------------

//  ---------------------------------------card/port delect/add--------------------------------------------
// 点击删除卡按钮操作
function mc_delect_card(obj) {
    var obj_remove = obj.parentNode.parentNode.parentNode;
    var str_card_name = obj_remove.getAttribute("card_name");
    var str_card_tip = obj.parentNode.children[0].innerText[0];
    var str_type = "_P";
    var ui_index = Number(str_card_name.substr(str_card_name.lastIndexOf("_") + 2));

    if ("H" === str_card_tip) {
        str_type = "_H";
    }
    if ("S" === str_card_tip) {
        str_type = "S";
    }
    mc_delect_port_data(str_card_name, str_card_name.substr(0, str_card_name.lastIndexOf("_")), ui_index, str_type);
    $(obj_remove).remove();
    mc_select_first_port();
    obj_operate_swiper.remove_slider([ui_index]);
    return true;
}

// 点击删除PORT按钮操作
function mc_delect_port(obj) {
    var e = window.event;
    var obj_remove = obj.parentNode.parentNode;
    var str_port_name = obj_remove.getAttribute("port_name");
    var str_card_name = str_port_name.substr(0, str_port_name.lastIndexOf("_"));
    var ui_idx = Number(obj_remove.getAttribute("idx"));
    var obj_swiper = parent.G_OBJ_WINDOW_DATA[str_card_name].obj_port_swiper;

    e.stopPropagation();
    // 数据处理
    $(obj_remove).remove();
    if (obj_swiper) {
        obj_swiper.remove_slider([ui_idx]);
        obj_swiper.judge_slider_range();
    }

    mc_delect_port_data(str_port_name, str_card_name, ui_idx, "_P");
    mc_update_card_show(str_card_name);
    mc_select_first_port();
    return true;
}

// 点击添加PORT按钮操作
function mc_add_port(obj) {
    var str_card_name = obj.parentNode.parentNode.getAttribute("card_name");
    // var ui_idx = obj.previousSibling.children.length;
    var ui_idx = $(obj.parentNode).children(".mc_port_box").children(".swiper-wrapper").children(".swiper-slide").children().length;
    var obj_param = mc_create_window_params(str_card_name + "_P" + ui_idx, ui_idx, 0, "CHILD", "MC_LANG_OUTPORT");

    // 记录添加port口数据
    update_g_obj_window_data(str_card_name + "_P" + ui_idx, obj_param);
    // 更新卡child_num
    update_g_obj_window_data(str_card_name, ui_idx + 1, "child_num");
    mc_create_port(obj_param, str_card_name);
    mc_select_first_port();
    // 更新card显示
    mc_update_card_show(str_card_name);
    return true;
}

// 点击重置端口按钮操作
function mc_reset_port(obj) {
    var str_card_name = obj.parentNode.getAttribute("reset_card_name");
    var $obj_card = $("#mc_window_box  [card_name='" + str_card_name + "']");
    var obj_card_data = parent.G_OBJ_WINDOW_DATA[str_card_name];
    var obj_update_data = obj_reset_data[str_card_name];

    if ($obj_card && obj_update_data && obj_card_data) {
        var ui_child_cnt = obj_card_data.child_num;

        // 更新PORT数据
        for (var i = 0; i < ui_child_cnt; i++) {
            var str_port_name = str_card_name + "_P" + i;
            var obj_port_data = parent.G_OBJ_WINDOW_DATA[str_port_name];

            if (obj_port_data) {
                mc_update_port_data(obj_port_data, obj_update_data, str_port_name);
            }
        }
        // 更新发送卡输入数据 card_img
        if (-1 === str_card_name.indexOf("_")) {
            mc_update_port_data(obj_card_data.card_img, obj_update_data, str_card_name);
        }
        mc_update_card_show(str_card_name);
    }
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    重置所有卡发送数据应用 -----发送所有卡输出端口图像、发送卡图像偏移数据(目前不进行发送)
 * 参数:
 *    @param { Promise<Object> } obj_json 重置宽高偏移数据
 * 返回：
 *     @return { Promise<Boolean> }
 *      false 参数有误
 *      true 设置成功
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2020.02.01
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_reset_all_send(obj_json) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_json)) {
        return false;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_json(JSON.stringify(obj_json));
    var obj_update_data = {
        width: obj_sdk_param.get_param_value("MC_LANG_W"),
        height: obj_sdk_param.get_param_value("MC_LANG_H"),
        left: obj_sdk_param.get_param_value("X"),
        top: obj_sdk_param.get_param_value("Y")
    };
    var obj_data = parent.G_OBJ_WINDOW_DATA;
    var arr_keys = Object.keys(obj_data);
    var arr_card_name = [];
    // 当前卡界面判定
    var obj_last_crumb = mc_get_crumb_lang_id();
    var str_type = obj_last_crumb.children("span").attr("lang_id");
    var b_sendcard = true;
    // var arr_hubport_img = [];
    var arr_sendcard_port = [];

    // hubcard
    if ("MC_LANG_HUB_CARD" === str_type) {
        b_sendcard = false;
    }

    for (var i = 0; i < arr_keys.length; i++) {
        var str_name = arr_keys[i];
        var obj_data_item = obj_data[str_name];
        var ui_type_len = str_name.split("_").length;
        var b_unset_edit = true;

        // 只修改当前页edit value
        if (b_sendcard && 3 > ui_type_len || !b_sendcard && 2 < ui_type_len) {
            b_unset_edit = false;
        }
        mc_update_port_data(obj_data_item, obj_update_data, str_name, b_unset_edit);
        // 更新发送卡输入数据 card_img
        if (-1 === str_name.indexOf("_")) {
            mc_update_port_data(obj_data_item.card_img, obj_update_data, str_name, b_unset_edit);
        }

        if ("P" !== str_name.substr(str_name.lastIndexOf("_") + 1)[0]) {
            arr_card_name.push(str_name);
        } else {
            // check：是否创建HUBPORT
            // mc_create_hubport_req_data(str_name, obj_data, obj_update_data, arr_hubport_img);
            arr_sendcard_port.push(str_name);
        }
    }
    // 更新CARD数据及页面显示
    for (var index = 0; index < arr_card_name.length; index++) {
        mc_update_card_show(arr_card_name[index], true);
    }

    // 检测是否存在HUB未请求构造数据 替换其输出端口数据
    mc_check_create_hub_data(arr_sendcard_port, function () {
        return true;
    }, obj_update_data);
    // 下发数据
    // if (0 === arr_card_name.length) {
    // // 无可发送数据
    //     mc_main_alert_popout("MC_LANG_POPOUT_NO_DATA_SEND");
    //     return true;
    // }
    // if (0 !== arr_hubport_img.length) {
    //     arr_card_name = arr_card_name.concat(arr_hubport_img);
    // }
    // mc_send_load(arr_card_name, b_load,false,true);
    return true;
}

//  ----------------------------------------------other----------------------------------------------------
// 清除card
function mc_clear_card() {
    $(".mc_card_box").remove();
    obj_operate_swiper.removeall_slider();
}

// PORT口点击事件 - 唯一选中 添加标识
function mc_select_port(obj) {
    $(".selected").removeClass("selected");
    $(obj).addClass("selected");
}

// 选中第一个PORT口
function mc_select_first_port() {
    var obj_select = $(".selected");

    if (0 !== obj_select.length) {
        obj_select.removeClass("selected");
    }
    if (0 !== $(".edit_box").length) {
        $(".edit_box").eq(0).addClass("selected");
    }
}

// 获取当前最后一个导航项crumb_item_text元素
function mc_get_crumb_lang_id() {
    return $("#mc_crumbs").children("div:last-child").children(".crumb_item_text");
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    当前存在HUB卡数量
 * 参数:
 *    @param { Promise<Object> } obj_data 卡数据
 * 返回：
 *    @return { Promise<Number> }
 *     -1 当前无卡
 *     其余Number  标识当前HUB卡数量
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.03.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_check_have_hubcard(obj_data) {
    if ("[object Object]" !== Object.prototype.toString.call(obj_data)) {
        return -1;
    }
    var arr_key = Object.keys(obj_data);

    if (0 === arr_key.length) {
        return -1;
    }
    var ui_hub_cnt = 0;

    // check sendport -> child_type === HUB
    for (var idx = 0; idx < arr_key.length; idx++) {
        var element = arr_key[idx];

        // check sendport
        if (2 === element.split("_").length) {
            var obj_sendport_data = obj_data[element];

            if (obj_sendport_data && "HUB" === obj_sendport_data.child_type) {
                ui_hub_cnt += Number(obj_sendport_data.child_num);
            }
        }
    }
    return ui_hub_cnt;
}


// **************************************** 分辨率 **************************************** //
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    读取发送卡dvi配置
 * 参数:
 *    @param { Promise<Number> } io 1 === 写 || 其他 === 读
 *    @param { Promise<Object> } params 请求参数对象; 内参数参考备注;
 *    @param { Promise<Function> } callback ; 回调参数(b_err,res); 1. b_err === true 请求错误 || b_err === false 请求成功;  2. res === 请求返回的json串
 * 返回:
 *    @returns { Promise<String> } 参数1
 * 例子:
 *    NA
 * 备注:
 *    params 对象需包含：
 *      index === 当前发送发下标；
 *      val === 当前设置的分配律的选项；
 *      str_custom === val值为 "USER_CFG" 时的请求 自定义分辨率值；格式 === "(宽:高:分辨率值)"
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function mc_io_hw_sendcard_dvi_cfg(io, params, callback) {
    if ("object" !== typeof params) {
        return false;
    }

    var obj_param = new mc_sdk_param();
    var srt_name_id = (params.index).toString();
    var str_user_cfg = "USER_CFG";

    obj_param.set_param_clear();
    obj_param.set_func("HW_SENDCARD_DVI_CFG");

    obj_param.set_cmd("GET_PARAM");
    obj_param.set_param_value(srt_name_id, "");

    if (1 === io) {
        obj_param.set_cmd("SET_PARAM");
        obj_param.set_param_value(srt_name_id, params.val.toString());
        if (params.val.toString() === str_user_cfg) {
            obj_param.set_attr_val(srt_name_id, str_user_cfg, params.str_custom);
        }
    }

    var str = obj_param.get_json();
    // console.log("[读取发送卡dvi配置请求参数]",io,JSON.parse(str));

    $.post("/access_shell", str, function (res, status) {
        if ("success" !== status) {
            return false;
        }
        obj_param.set_param_clear();
        obj_param.set_json(res);

        // var str_res = obj_param.get_json();
        // console.log("[dvi配置请求返回]",io,JSON.parse(str_res));

        var str_err = obj_param.get_param_value("ERROR_CODE");
        var str_err_req = obj_param.get_attr_val(srt_name_id, "ERROR_CODE");

        if ("function" === typeof callback) {
            var err = false;
            var error_code = "0x00000000";

            if (error_code !== str_err && str_err) {
                return callback(true, res);
            }

            if (str_err_req) {
                if (error_code !== str_err_req && str_err) {
                    return callback(true, res);
                }
            }

            return callback(err, res);
        }

        return true;
    }, "text");

    return true;
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    构造分辨率控件(包含控件和自定义按钮)
 * 参数:
 *    @param { Promise<String> } str_json 获取硬件分辨率返回的json字串
 *    @param { Promise<Object> } obj_card 卡数据
 * 返回:
 *    @returns { Promise<String> } 构建html的字符串
 * 例子:
 *    NA
 * 备注:
 *    1. 当前函数下在原始卡数据添加 dvi_cfg 属性值对象 === 分辨率数据
 *    dvi_cfg 该对象下的属性值：
 *    obj_item === 构造控件的对象；
 *    opt === 控件的下拉列表选项值
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function construct_item_dvi_cfg(str_json, obj_card) {
    var obj_param = new mc_sdk_param();
    var srt_name_id = (obj_card.index).toString();

    obj_param.set_json(str_json);

    var arr_name_val = obj_param.get_param_value(srt_name_id);

    // 获取下拉列表选项数组
    var arr_opt = construct_dvi_cfg_options_arr(srt_name_id, obj_param);

    // var str = obj_param.get_json();
    // console.log("[构造控件参数]",JSON.parse(str));

    var obj_item_sel = new mc_ui_select();

    if (arr_opt) {
        obj_item_sel.set_arr(arr_opt.opt);
        // 保存自定义值
        obj_card.dvi_cfg = {
            // 构造控件的对象
            obj_item: obj_item_sel,
            // 控件的下拉列表选项值
            opt: arr_opt.opt
        };
    }

    obj_item_sel.set_style_width("280px");
    obj_item_sel.set_val(arr_name_val);
    obj_item_sel.on_val_chg = update_card_dvi_cfg;

    // 当前分辨率
    var str_cut_dvi = "<div class='item_wrap' style='height:auto;text-align:center;width:90%'>" + g_obj_lang.get_item_val("MC_LANG_RESOLUTION") + ": " + arr_opt.cur + "</div>";
    // 控件和图标
    var str_btn_html = "<div class='mc_btn mc_btn_dvi_cfg icon-edit' lang_id='' id='' title='" + g_obj_lang.get_item_val("MC_LANG_BTN_CUSTOM") + "' onclick='mc_custom_dvi_cfg(this)'>" + "" + "</div>";

    return "<div class='item_wrap'>" + obj_item_sel.get_html_txt() + "</div>" + str_btn_html + str_cut_dvi;
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取下拉选项列表数组
 * 参数:
 *    @param { Promise<String> } str_name 接收卡下标
 *    @param { Promise<Object> } obj_sdk_param 解析读取硬件返回json串的 mc_sdk_param 实例对象
 * 返回:
 *    @returns { Promise<Object> } { opt:返回下拉列表控件的数组, cur: json串 DVI_STATUS 的值 } || false
 * 例子:
 *    NA
 * 备注:
 *    1. 当有 "USER_CFG" 选项的数据时需要放在返回数据的第一个 && 提示语为"自定义"
 *    2. 增加 "DVI_STATUS" 判断, 表示当前连接的分辨率;
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function construct_dvi_cfg_options_arr(str_name, obj_sdk_param) {
    if ("object" === typeof obj_sdk_param) {
        var ui_cnt = obj_sdk_param.get_attr_cnt(str_name);
        var arr_res = [];
        var str_left = "(";
        var str_right = ")";
        var str_x = "x";
        var str_aite = " ";
        var str_hz = "Hz";
        var str_cur_dvi = "";


        for (var ui_i = 0; ui_i < ui_cnt; ui_i++) {
            var str_attr_name = obj_sdk_param.get_attr_name(str_name, ui_i);
            var str_attr_val = obj_sdk_param.get_attr_val(str_name, str_attr_name);

            if ("ERROR_CODE" === str_attr_name) {
                continue;
            }

            if (str_attr_val) {
                if (-1 !== str_attr_val.indexOf(str_left)) {
                    str_attr_val = str_attr_val.split(str_left)[1];
                }

                if (-1 !== str_attr_val.indexOf(str_right)) {
                    str_attr_val = str_attr_val.split(str_right)[0];
                }

                var str_no_parentheses = str_attr_val;
                var b_zero = new RegExp("[1-9]").test(str_no_parentheses);

                str_attr_val = str_no_parentheses.replace(":", str_x);
                str_attr_val = str_attr_val.replace(":", str_aite);

                var str_opt_val = str_attr_val + str_hz;

                if ("DVI_STATUS" === str_attr_name) {
                    if (is_hex(str_no_parentheses)) {
                        str_cur_dvi = str_no_parentheses;
                    } else {
                        str_cur_dvi = str_opt_val;
                    }
                    continue;
                }

                if (!b_zero) {
                    arr_res[ui_i] = str_attr_name + "=" + g_obj_lang.get_item_val("MC_LANG_PRE_SETUP") + ": " + str_opt_val + "(" + g_obj_lang.get_item_val("MC_LANG_OPTION_AUTO") + ")";
                    continue;
                }

                if ("USER_CFG" === str_attr_name) {
                    arr_res.unshift(str_attr_name + "=" + g_obj_lang.get_item_val("MC_LANG_BTN_CUSTOM") + ": " + str_opt_val);
                } else {
                    arr_res[ui_i] = str_attr_name + "=" + g_obj_lang.get_item_val("MC_LANG_PRE_SETUP") + ": " + str_opt_val;
                }
            }
        }

        return {
            cur: str_cur_dvi,
            opt: arr_res.filter(function (val) {
                return val;
            })
        };
    }

    // 判断是否为16进制
    function is_hex(str) {
        if ("string" !== typeof str) {
            str.toString();
        }

        if (str.toLowerCase().match(/^0x/)) {
            return true;
        }

        return false;
    }

    return false;
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    分辨率下拉列表值更新回调
 * 参数:
 *    @param { Promise<String> } id 控件id
 *    @param { Promise<String> } val 控件选项key
 * 返回:
 *    NA
 * 例子:
 *    NA
 * 备注:
 *    更新操作需要向硬件下发数据；
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function update_card_dvi_cfg(id, val) {
    // console.log("[分辨率更新]",id, val);

    var obj_opt = document.getElementById(id);

    if (obj_opt) {
        var $obj_parent = $(obj_opt).parents(".mc_card_box");

        if ($obj_parent.length) {
            var str_card_name = $obj_parent[0].getAttribute("card_name");
            var obj_card_data = parent.G_OBJ_WINDOW_DATA[str_card_name];

            mc_dvi_update_send_to_sdk(obj_card_data, val);
        }
    }
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    下拉框更新; 更新操作需要向硬件下发数据；
 * 参数:
 *    @param { Promise<Object> } obj_card_data 当前发送卡数据
 *    @param { Promise<String> } val 当前发送卡分分辨率选项值; 下拉框更新值
 * 返回:
 *    NA
 * 例子:
 *    NA
 * 备注:
 *    NA
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2021-06-01
 *       内容 : 所有代码; 拆分封装代码
************************************************************************************************/
function mc_dvi_update_send_to_sdk(obj_card_data, val) {
    if ("object" === typeof obj_card_data) {
        var obj_param = {
            index: obj_card_data.index,
            val: val
        };

        if ("USER_CFG" === val) {
            var obj_custom = get_custom_opt(obj_card_data);
            var str_custom = "(" + obj_custom.W + ":" + obj_custom.H + ":" + obj_custom.HZ + ")";

            obj_param.str_custom = str_custom;
        }

        mc_io_hw_sendcard_dvi_cfg(1, obj_param, function (err) {
            if (!err) {
                // alert("发送成功");
            }
        });
    }
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    点击自定义按钮；需要打开自定义编辑弹框
 * 参数:
 *    @param { Promise<Object> } obj 点击操作的当前按钮dom对象
 * 返回:
 *    NA
 * 例子:
 *    NA
 * 备注:
 *    NA
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function mc_custom_dvi_cfg(obj) {
    if (obj) {
        var $obj_parent = $(obj).parents(".mc_card_box");

        if ($obj_parent) {
            var str_card_name = $obj_parent[0].getAttribute("card_name");

            mc_dvi_open_custom(str_card_name, parent.G_OBJ_WINDOW_DATA[str_card_name], function (o_param) {
                if ("object" === typeof o_param) {
                    mc_dvi_modify_opt(o_param, parent.G_OBJ_WINDOW_DATA[o_param.NAME]);
                }
            });
        }
    }
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    打开自定义弹窗
 * 参数:
 *    @param { Promise<String> } str_card_name 当前保存的发动卡名称; 全局保存数据对象保存的卡名称一致; 对象key
 *    @param { Promise<Object> } obj_card_data 当前发送卡数据
 *    @param { Promise<Function> } fn 自定义弹窗确认回调函数
 * 返回:
 *    NA
 * 例子:
 *    NA
 * 备注:
 *    NA
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2021-06-01
 *       内容 : 所有代码; 拆分封装代码
************************************************************************************************/
function mc_dvi_open_custom(str_card_name, obj_card_data, fn) {
    if ("object" !== typeof obj_card_data || "string" !== typeof str_card_name) {
        return;
    }

    var obj_def = get_custom_opt(obj_card_data);
    var str_param = "";

    if (obj_def) {
        str_param = "&width=" + obj_def.W + "&height=" + obj_def.H + "&hz=" + obj_def.HZ;
    }

    var str_url = "./pages/mc_window/mc_window_custom.html?card_name=" + str_card_name + str_param;
    var obj_popout = {
        icon: "icon-edit",
        title: "MC_LANG_BTN_CUSTOM",
        url: str_url,
        area: ["300px", "100%"],
        set_move: ".layui-layer-title",
        skin: "layui-anim layui-anim-rl layui-layer-adminRight level_st"
    };

    parent.G_FN_CUSTOM_CALLBACK = fn;
    // parent.mc_iframe_popout(obj_popout);
    // 打开弹层页面
    parent.G_OBJ_ROUTER_PAGE.set_popup_layer_msg(obj_popout);
    parent.G_OBJ_ROUTER_PAGE.open_popup_layer();
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    自定义弹框确定回调 -> 修改选项
 * 参数:
 *    @param { Promise<Object> } obj_data 回调返回数据对象;属性值参考备注
 *    @param { Promise<Object> } obj_cur_card 当前发送卡数据对象
 * 返回:
 *    NA
 * 例子:
 *    NA
 * 备注:
 *    obj属性值：
 *    NAME === 卡名称
 *    W === 宽
 *    H === 高
 *    HZ === 分辨率
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function mc_dvi_modify_opt(obj_data, obj_cur_card) {
    // console.log("[应用回调]", obj);
    if ("object" !== typeof obj_data || "object" !== typeof obj_cur_card) {
        return;
    }

    // var str_custom = "(" + obj_data.W + ":" + obj_data.H + ":" + obj_data.HZ + ")";
    var str_key = "USER_CFG";
    var str_x = "x";
    var str_aite = " ";
    var str_hz = "Hz";

    //  eg: USER_CFG=预设: 1920x523 6000.00HZ
    var str_val = obj_data.W + str_x + obj_data.H + str_aite + obj_data.HZ + str_hz;
    var str_opt_i = str_key + "=" + g_obj_lang.get_item_val("MC_LANG_BTN_CUSTOM") + ": " + str_val;

    if (obj_cur_card) {
        var arr_old = obj_cur_card.dvi_cfg;

        if (arr_old) {
            if (-1 !== JSON.stringify(arr_old.opt).indexOf(str_key)) {
                var ui_len = arr_old.opt.length;

                for (var ui_i = 0; ui_i < ui_len; ui_i++) {
                    var item = arr_old.opt[ui_i];

                    if (-1 !== item.indexOf(str_key)) {
                        arr_old.opt[ui_i] = str_opt_i;
                        break;
                    }
                }
            } else {
                arr_old.opt.unshift(str_opt_i);
            }

            var obj_item = arr_old.obj_item;

            if (obj_item) {
                obj_item.set_dom_arr(arr_old.opt);
            }
        }
    }
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    获取自定义选项
 * 参数:
 *    @param { Promise<Object> } obj 当前卡数据对象
 * 返回:
 *    @returns { Promise<Object> } obj_res 返回当前卡选项的自定义选项对象； 默认值为: 宽高 === 768 ; HZ === 60
 * 例子:
 *    NA
 * 备注:
 *    NA
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2020-12-01
 *       内容 : 所有代码
************************************************************************************************/
function get_custom_opt(obj) {
    var obj_res = {
        W: Number(768),
        H: Number(768),
        HZ: Number(60)
    };

    var str_x = "x";
    var str_aite = " ";
    var str_hz = "Hz";

    if (obj) {
        var arr_old = obj.dvi_cfg;
        var str_key = "USER_CFG";

        if (arr_old) {
            if (-1 !== JSON.stringify(arr_old.opt).indexOf(str_key)) {
                var ui_len = arr_old.opt.length;

                for (var ui_i = 0; ui_i < ui_len; ui_i++) {
                    var item = arr_old.opt[ui_i];

                    if (-1 !== item.indexOf(str_key)) {
                        var ui_idx = item.indexOf(":");
                        var str_useful = item.substring(ui_idx + 1, item.length);
                        var arr = str_useful.trim().split(str_aite);
                        var ui_w = arr[0].split(str_x)[0].trim();
                        var ui_h = arr[0].split(str_x)[1].trim();
                        var ui_hz = arr[1].trim().replace(str_hz, "");

                        obj_res = {
                            W: Number(ui_w),
                            H: Number(ui_h),
                            HZ: Number(ui_hz)
                        };

                        return obj_res;
                    }
                }
            }
        }
    }

    return obj_res;
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    发送卡输出口备份
 * 参数:
 *    @param {Promise<String>} str_order     指令
 *    @param {Promise<String>} str_val     主辅参数
 *    @param {Promise<String>} str_memtype     数据类型(固化FLASH , 发送RAM)
 *    @param {Promise<String>} str_cur_ctrl_card     主控芯片名称
 *    @param {Promise<function>} fun_callback     回调函数

 * 返回：
 *    @param {Promise<String>} error 错误码
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 李智明
 *      时 间 : 2021.2.05
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_send_port_backup(str_order, str_val, str_memtype, str_cur_ctrl_card, fun_callback) {
    if ("function" !== typeof fun_callback) {
        fun_callback("");
        return;
    }

    var obj_box_offset_req = new mc_sdk_param();

    obj_box_offset_req.set_param_clear();
    obj_box_offset_req.set_cmd("SET_PARAM");
    obj_box_offset_req.set_func("HW_SENDCARD_OUTPORT_BACKUP");
    obj_box_offset_req.set_param_value(str_order, str_val);
    if (str_cur_ctrl_card) {
        obj_box_offset_req.set_attr_val(str_order, "CHIPNAME", str_cur_ctrl_card);
    }
    obj_box_offset_req.set_attr_val(str_order, "MEMTYPE", str_memtype);


    $.post("/access_shell", obj_box_offset_req.get_json(), function (result, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        var obj_res = new mc_sdk_param();

        obj_res.set_json(result);
        var error = obj_res.get_param_value("ERROR_CODE");

        fun_callback(error);
        return;
    });
}


/************************************************************************************************
* 类型:
*    函数
* 功能:
*    HUB卡备份
* 参数:
*    @param {Promise<String>} str_order     指令
*    @param {Promise<String>} str_val     enable/disable 启用参数
*    @param {Promise<String>} str_memtype     数据类型(固化FLASH , 发送RAM)
*    @param {Promise<String>} str_cur_ctrl_card     主控芯片名称
*    @param {Promise<function>} fun_callback     回调函数

* 返回：
*    @param {Promise<String>} error 错误码

* 修改:
*   1. 类型 : 创建
*      作者 : 李智明
*      时 间 : 2021.2.05
*      内容 : 所有代码
************************************************************************************************/
function mc_hub_card_backup(str_order, str_val, str_memtype, str_cur_ctrl_card, fun_callback) {
    if ("function" !== typeof fun_callback) {
        fun_callback("");
        return;
    }

    var obj_box_offset_req = new mc_sdk_param();

    str_order = "(" + str_order + ")";
    obj_box_offset_req.set_param_clear();
    obj_box_offset_req.set_cmd("SET_PARAM");
    obj_box_offset_req.set_func("HW_HUBCARD_BACKUP");
    obj_box_offset_req.set_param_value(str_order, str_val);
    if (str_cur_ctrl_card) {
        obj_box_offset_req.set_attr_val(str_order, "CHIPNAME", str_cur_ctrl_card);
    }
    obj_box_offset_req.set_attr_val(str_order, "MEMTYPE", str_memtype);


    $.post("/access_shell", obj_box_offset_req.get_json(), function (result, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        var obj_res = new mc_sdk_param();

        obj_res.set_json(result);
        var error = obj_res.get_param_value("ERROR_CODE");

        fun_callback(error);
        return;
    });
}

// **************************************** Swiper ************************************** //
/************************************************************************************************
* 类型:
*    函数
* 功能:
*    卡轮播
* 参数:
*    @param {Promise<Object>} obj_swiper swiper对象
* 修改:
*   1. 类型 : 创建
*      作者 : 陈小荟
*      时 间 : 2021.04.25
*      内容 : 所有代码
************************************************************************************************/
function mc_operate_swiper_slider(obj_swiper) {
    // 当前数据条数 (不记录默认)
    var ui_data_cnt = 0;
    // 当前slider下标
    var ui_before_progress = 1;
    // 是否创建默认项 默认创建
    var b_create_default = true;
    // slider class
    var str_slider_class = "";
    var ui_slider_height = 0;

    // 添加slider项 接受HTML字串（添加单个）
    this.add_slider = function (str_html) {
        if ("[object String]" !== Object.prototype.toString.call(str_html)) {
            return false;
        }
        if (0 === ui_data_cnt && b_create_default) {
            // 将默认项去除
            obj_swiper.removeSlide(0);
        }
        str_html = "<div class='swiper-slide " + str_slider_class + "'>" + str_html + "</div>";
        obj_swiper.appendSlide(str_html);
        obj_swiper.update();
        ui_data_cnt += 1;
        return true;
    };

    // 移除slider项; 接受数组形式删除下标（删除多个）
    this.remove_slider = function (arr_index) {
        if ("[object Array]" !== Object.prototype.toString.call(arr_index)) {
            return false;
        }
        obj_swiper.removeSlide(arr_index);
        ui_data_cnt -= arr_index.length;

        // 清空展示默认项
        if (0 === ui_data_cnt && b_create_default) {
            obj_swiper.appendSlide(this.get_default_html());
        }
        obj_swiper.update();
        return true;
    };

    // 更新swiper
    this.update_swiper = function () {
        obj_swiper.update();
    };

    // 切换到指定slide
    this.slideto_slide = function (ui_progress) {
        if ("[object Number]" !== Object.prototype.toString.call(ui_progress) || ui_progress === ui_before_progress) {
            return false;
        }
        obj_swiper.slideTo(ui_progress - 1, 500, false);
        ui_before_progress = ui_progress;
        return true;
    };

    // 清空所有slide
    this.removeall_slider = function () {
        obj_swiper.removeAllSlides();
        if (b_create_default) {
            obj_swiper.appendSlide(this.get_default_html());
        }
        ui_data_cnt = 0;
    };

    // 获取默认项标签 翻译过后
    this.get_default_html = function () {
        var str_lang = g_obj_lang.get_item_val("MC_LANG_NOT_CARD_DATA");

        return "<div class='swiper-slide " + str_slider_class + "' style='font-size:18px;color:#fff;'>" + str_lang + "</div>";
    };

    // 更新当前slider下标
    this.update_slider_progress = function (ui_progress) {
        if ("[object Number]" !== Object.prototype.toString.call(ui_progress)) {
            return false;
        }
        ui_before_progress = ui_progress;
        return true;
    };

    // 设置是否创建默认项
    this.set_create_default = function (b_create) {
        if ("[object Boolean]" !== Object.prototype.toString.call(b_create)) {
            return false;
        }
        b_create_default = b_create;
        return true;
    };

    // 设置slider class
    this.set_slider_class = function (str_class) {
        if ("[object String]" !== Object.prototype.toString.call(str_class)) {
            return false;
        }
        str_slider_class = str_class;
        return true;
    };

    // 判断当前是否超出显示范围 超出显示按钮 否则隐藏
    this.judge_slider_range = function () {
        if (!ui_slider_height) {
            ui_slider_height = obj_swiper.slides[0].offsetHeight;
        }
        var ui_slider_cnt = obj_swiper.slides.length;
        var ui_btn_height = 42;
        var obj_swiper_container = obj_swiper.el;

        if (0 > obj_swiper_container.offsetHeight - ui_btn_height - ui_slider_height * ui_slider_cnt) {
            obj_swiper_container.previousSibling.style.display = "block";
            obj_swiper_container.nextSibling.style.display = "block";
        } else {
            obj_swiper_container.previousSibling.style.display = "none";
            obj_swiper_container.nextSibling.style.display = "none";
            obj_swiper.slideTo(0);
        }
        return true;
    };
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    更新PORT SLIDEER 上下按钮显示
 * 参数:
 *    NA
 * 返回：
 *    @return { Promise<Boolean> }
 *     true
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 陈小荟
 *      时间 : 2021.05.10
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_update_slider_range() {
    var ui_len = document.getElementsByClassName("crumb_item").length;
    var obj_data = parent.G_OBJ_WINDOW_DATA;
    var arr_key = Object.keys(obj_data);
    var arr_card_name = [];

    if (1 === ui_len) {
        arr_card_name = mc_filter_tool(function (item) {
            return -1 === item.indexOf("_");
        }, arr_key);
    } else {
        arr_card_name = mc_filter_tool(function (item) {
            return -1 !== item.indexOf("_") && "P" !== item.substr(item.lastIndexOf("_") + 1, 1);
        }, arr_key);
    }

    for (var index = 0; index < arr_card_name.length; index++) {
        var obj_swiper = obj_data[arr_card_name[index]].obj_port_swiper;

        if (obj_swiper) {
            obj_swiper.judge_slider_range();
        }
    }
    return true;
}


